[tracker] Ensure video size is extracted by libav extractor.



commit 608c63fb9e0613e42779a844afff4fd4ee04a033
Author: Andrew den Exter <andrew den exter jollamobile com>
Date:   Tue Oct 22 03:28:08 2013 +0000

    Ensure video size is extracted by libav extractor.
    
    It may be necessary to parse the MPEG bitstream to get width and height
    from some videos so if the resolution isn't immediately available decode
    enough data to determine it.

 src/tracker-extract/Makefile.am             |    5 +-
 src/tracker-extract/tracker-extract-libav.c |   96 ++++++++++++++++++++++-----
 2 files changed, 83 insertions(+), 18 deletions(-)
---
diff --git a/src/tracker-extract/Makefile.am b/src/tracker-extract/Makefile.am
index bb8296e..5ec6b66 100644
--- a/src/tracker-extract/Makefile.am
+++ b/src/tracker-extract/Makefile.am
@@ -506,8 +506,9 @@ libextract_libav_la_LIBADD = \
        $(top_builddir)/src/libtracker-common/libtracker-common.la \
        $(BUILD_LIBS) \
        $(TRACKER_EXTRACT_MODULES_LIBS) \
-        $(AVFORMAT_LIBS) \
-        $(AVUTIL_LIBS)
+       $(AVFORMAT_LIBS) \
+       $(AVUTIL_LIBS) \
+       $(AVCODEC_LIBS)
 
 
 #
diff --git a/src/tracker-extract/tracker-extract-libav.c b/src/tracker-extract/tracker-extract-libav.c
index 1414b5d..3c71807 100644
--- a/src/tracker-extract/tracker-extract-libav.c
+++ b/src/tracker-extract/tracker-extract-libav.c
@@ -123,7 +123,10 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
        AVFormatContext *format = NULL;
        AVStream *audio_stream = NULL;
        AVStream *video_stream = NULL;
-       int streamIndex;
+       AVCodec *audio_codec = NULL;
+       AVCodec *video_codec = NULL;
+       int audio_stream_index;
+       int video_stream_index;
        AVDictionaryEntry *tag = NULL;
        const char *title = NULL;
 
@@ -143,14 +146,14 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
        }
        g_free (absoluteFilePath);
 
-       streamIndex = av_find_best_stream (format, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
-       if (streamIndex >= 0) {
-               audio_stream = format->streams[streamIndex];
+       audio_stream_index = av_find_best_stream (format, AVMEDIA_TYPE_AUDIO, -1, -1, &audio_codec, 0);
+       if (audio_stream_index >= 0) {
+               audio_stream = format->streams[audio_stream_index];
        }
 
-       streamIndex = av_find_best_stream (format, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
-       if (streamIndex >= 0) {
-               video_stream = format->streams[streamIndex];
+       video_stream_index = av_find_best_stream (format, AVMEDIA_TYPE_VIDEO, -1, -1, &video_codec, 0);
+       if (video_stream_index >= 0) {
+               video_stream = format->streams[video_stream_index];
        }
 
        if (!audio_stream && !video_stream) {
@@ -158,6 +161,45 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
                return FALSE;
        }
 
+       if (audio_stream) {
+               if (audio_stream->codec->sample_rate > 0) {
+                       set_value_int64 (metadata, "nfo:sampleRate", audio_stream->codec->sample_rate);
+               } else if (avcodec_open2(audio_stream->codec, audio_codec, 0) >= 0) {
+                       AVFrame *frame;
+                       AVPacket packet;
+                       av_init_packet(&packet);
+
+                       frame = avcodec_alloc_frame();
+
+                       for (;;) {
+                               int decoded = 0;
+                               if (av_read_frame (format, &packet) < 0) {
+                                       break;
+                               } else if (packet.stream_index != audio_stream_index) {
+                               } else if (!avcodec_decode_audio4(
+                                       audio_stream->codec, frame, &decoded, &packet) < 0) {
+                                       av_free_packet(&packet);
+                                       break;
+                               } else if (audio_stream->codec->sample_rate > 0) {
+                                       set_value_int64 (metadata, "nfo:sampleRate",
+                                                        audio_stream->codec->sample_rate);
+                                       break;
+                               }
+                               av_free_packet(&packet);
+
+                               if (decoded) {
+                                       break;
+                               }
+                       }
+                       av_free(frame);
+
+                       avcodec_close(audio_stream->codec);
+               }
+               if (audio_stream->codec->channels > 0) {
+                       set_value_int64 (metadata, "nfo:channels", audio_stream->codec->channels);
+               }
+       }
+
        if (video_stream) {
                tracker_sparql_builder_predicate (metadata, "a");
                tracker_sparql_builder_object (metadata, "nmm:Video");
@@ -165,6 +207,37 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
                if (video_stream->codec->width > 0 && video_stream->codec->height > 0) {
                        set_value_int64 (metadata, "nfo:width", video_stream->codec->width);
                        set_value_int64 (metadata, "nfo:height", video_stream->codec->height);
+               } else if (avcodec_open2(video_stream->codec, video_codec, 0) >= 0) {
+                       AVFrame *frame;
+                       AVPacket packet;
+                       av_init_packet(&packet);
+
+                       frame = avcodec_alloc_frame();
+
+                       av_seek_frame(format, video_stream_index, -1, 0);
+                       for (;;) {
+                               int decoded = 0;
+                               if (av_read_frame(format, &packet) < 0) {
+                                       break;
+                               } else if (packet.stream_index != video_stream_index) {
+                               } else if (!avcodec_decode_video2(
+                                       video_stream->codec, frame, &decoded, &packet) < 0) {
+                                       av_free_packet(&packet);
+                                       break;
+                               } else if (video_stream->codec->width > 0 && video_stream->codec->height > 0) 
{
+                                       set_value_int64 (metadata, "nfo:width", video_stream->codec->width);
+                                       set_value_int64 (metadata, "nfo:height", video_stream->codec->height);
+                                       break;
+                               }
+                               av_free_packet(&packet);
+
+                               if (decoded) {
+                                       break;
+                               }
+                       }
+                       av_free(frame);
+
+                       avcodec_close(video_stream->codec);
                }
 
                if (video_stream->avg_frame_rate.num > 0) {
@@ -313,15 +386,6 @@ tracker_extract_get_metadata (TrackerExtractInfo *info)
                                           uri);
        }
 
-       if (audio_stream) {
-               if (audio_stream->codec->sample_rate > 0) {
-                       set_value_int64 (metadata, "nfo:sampleRate", audio_stream->codec->sample_rate);
-               }
-               if (audio_stream->codec->channels > 0) {
-                       set_value_int64 (metadata, "nfo:channels", audio_stream->codec->channels);
-               }
-       }
-
        if (format->bit_rate > 0) {
                set_value_int64 (metadata, "nfo:averageBitrate", format->bit_rate);
        }


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]