aboutsummaryrefslogtreecommitdiff
path: root/src/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/Makefile.am25
-rw-r--r--src/plugins/mpeg_extractor.c171
-rw-r--r--src/plugins/test_mpeg.c88
-rw-r--r--src/plugins/testdata/mpeg_melt.mpgbin0 -> 190646 bytes
4 files changed, 205 insertions, 79 deletions
diff --git a/src/plugins/Makefile.am b/src/plugins/Makefile.am
index b580ade..a7652dd 100644
--- a/src/plugins/Makefile.am
+++ b/src/plugins/Makefile.am
@@ -42,12 +42,19 @@ PLUGIN_FLAC=libextractor_flac.la
42TEST_FLAC=test_flac 42TEST_FLAC=test_flac
43endif 43endif
44 44
45if HAVE_MPEG2
46PLUGIN_MPEG=libextractor_mpeg.la
47TEST_MPEG=test_mpeg
48endif
49
50
45plugin_LTLIBRARIES = \ 51plugin_LTLIBRARIES = \
46 $(PLUGIN_OGG) \ 52 $(PLUGIN_OGG) \
47 $(PLUGIN_MIME) \ 53 $(PLUGIN_MIME) \
48 $(PLUGIN_GIF) \ 54 $(PLUGIN_GIF) \
49 $(PLUGIN_RPM) \ 55 $(PLUGIN_RPM) \
50 $(PLUGIN_FLAC) 56 $(PLUGIN_FLAC) \
57 $(PLUGIN_MPEG)
51 58
52if HAVE_ZZUF 59if HAVE_ZZUF
53 fuzz_tests=fuzz_default.sh 60 fuzz_tests=fuzz_default.sh
@@ -58,7 +65,8 @@ check_PROGRAMS = \
58 $(TEST_MIME) \ 65 $(TEST_MIME) \
59 $(TEST_GIF) \ 66 $(TEST_GIF) \
60 $(TEST_RPM) \ 67 $(TEST_RPM) \
61 $(TEST_FLAC) 68 $(TEST_FLAC) \
69 $(TEST_MPEG)
62 70
63TESTS = \ 71TESTS = \
64 $(fuzz_tests) \ 72 $(fuzz_tests) \
@@ -140,3 +148,16 @@ test_flac_LDADD = \
140 $(top_builddir)/src/plugins/libtest.la 148 $(top_builddir)/src/plugins/libtest.la
141 149
142 150
151libextractor_mpeg_la_SOURCES = \
152 mpeg_extractor.c
153libextractor_mpeg_la_LDFLAGS = \
154 $(PLUGINFLAGS)
155libextractor_mpeg_la_LIBADD = \
156 -lmpeg2
157
158test_mpeg_SOURCES = \
159 test_mpeg.c
160test_mpeg_LDADD = \
161 $(top_builddir)/src/plugins/libtest.la
162
163
diff --git a/src/plugins/mpeg_extractor.c b/src/plugins/mpeg_extractor.c
index 6c68b4a..dfc7ecb 100644
--- a/src/plugins/mpeg_extractor.c
+++ b/src/plugins/mpeg_extractor.c
@@ -1,11 +1,11 @@
1 1
2/* 2/*
3 This file is part of libextractor. 3 This file is part of libextractor.
4 (C) 2004, 2005, 2006, 2009 Vidyut Samanta and Christian Grothoff 4 (C) 2004, 2005, 2006, 2009, 2012 Vidyut Samanta and Christian Grothoff
5 5
6 libextractor is free software; you can redistribute it and/or modify 6 libextractor is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published 7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2, or (at your 8 by the Free Software Foundation; either version 3, or (at your
9 option) any later version. 9 option) any later version.
10 10
11 libextractor is distributed in the hope that it will be useful, but 11 libextractor is distributed in the hope that it will be useful, but
@@ -19,98 +19,115 @@
19 Boston, MA 02111-1307, USA. 19 Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22/**
23 * @file plugins/mpeg_extractor.c
24 * @brief plugin to support MPEG files
25 * @author Christian Grothoff
26 */
22#include "platform.h" 27#include "platform.h"
23#include "extractor.h" 28#include "extractor.h"
24#include <mpeg2dec/mpeg2.h> 29#include <mpeg2dec/mpeg2.h>
25 30
26#define ADD(s,t) do { if (0 != (ret = proc (proc_cls, "mpeg", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen(s)+1))) goto EXIT; } while (0) 31
32/**
33 * Give meta data to extractor.
34 *
35 * @param t type of the meta data
36 * @param s meta data value in utf8 format
37 */
38#define ADD(s,t) do { if (0 != ec->proc (ec->cls, "mpeg", t, EXTRACTOR_METAFORMAT_UTF8, "text/plain", s, strlen (s) + 1)) goto EXIT; } while (0)
27 39
28 40
29/* video/mpeg */ 41/**
30int 42 * Main entry method for the 'video/mpeg' extraction plugin.
31EXTRACTOR_mpeg_extract (const unsigned char *data, 43 *
32 size_t size, 44 * @param ec extraction context provided to the plugin
33 EXTRACTOR_MetaDataProcessor proc, 45 */
34 void *proc_cls, 46void
35 const char *options) 47EXTRACTOR_mpeg_extract_method (struct EXTRACTOR_ExtractContext *ec)
36{ 48{
37 mpeg2dec_t *handle; 49 mpeg2dec_t *handle;
38 uint8_t *start;
39 uint8_t *end;
40 const mpeg2_info_t *info; 50 const mpeg2_info_t *info;
51 void *buf;
52 ssize_t avail;
41 mpeg2_state_t state; 53 mpeg2_state_t state;
42 int ret;
43 char format[256]; 54 char format[256];
55 int finished;
44 56
45 if ((size < 4) || 57 if (NULL == (handle = mpeg2_init ()))
46 (!((data[0] == 0x00) && 58 return;
47 (data[1] == 0x00) && 59 if (NULL == (info = mpeg2_info (handle)))
48 (data[2] == 0x01) && ((data[3] == 0xB3) || (data[3] == 0xBA)))))
49 return 0;
50
51 handle = mpeg2_init ();
52 if (handle == NULL)
53 return 0;
54 start = (uint8_t *) data;
55 end = (uint8_t *) & data[size];
56 mpeg2_buffer (handle, start, end);
57 state = mpeg2_parse (handle);
58 if (state != STATE_SEQUENCE)
59 { 60 {
60 mpeg2_close (handle); 61 mpeg2_close (handle);
61 return 0; 62 return;
62 } 63 }
63 info = mpeg2_info (handle); 64 finished = 3;
64 if (info == NULL) 65 while (0 != finished)
65 { 66 {
66 mpeg2_close (handle); 67 state = mpeg2_parse (handle);
67 return 0; 68 switch (state)
68 } 69 {
69 ret = 0; 70 case STATE_BUFFER:
70 ADD ("video/mpeg", EXTRACTOR_METATYPE_MIMETYPE); 71 if (0 >= (avail = ec->read (ec->cls,
71 if (info->sequence != NULL) 72 &buf,
72 { 73 16 * 1024)))
73 snprintf (format, 74 goto EXIT;
74 sizeof(format), "%ux%u", 75 mpeg2_buffer (handle, buf, buf + avail);
75 info->sequence->width, info->sequence->height); 76 break;
76 ADD (format, EXTRACTOR_METATYPE_IMAGE_DIMENSIONS); 77 case STATE_SEQUENCE:
77 switch (info->sequence->flags & SEQ_VIDEO_FORMAT_UNSPECIFIED) 78 ADD ("video/mpeg", EXTRACTOR_METATYPE_MIMETYPE);
78 { 79 snprintf (format,
79 case SEQ_VIDEO_FORMAT_PAL: 80 sizeof(format), "%ux%u",
80 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 81 info->sequence->width, info->sequence->height);
81 break; 82 ADD (format, EXTRACTOR_METATYPE_IMAGE_DIMENSIONS);
82 case SEQ_VIDEO_FORMAT_NTSC: 83 switch (info->sequence->flags & SEQ_VIDEO_FORMAT_UNSPECIFIED)
83 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 84 {
84 break; 85 case SEQ_VIDEO_FORMAT_PAL:
85 case SEQ_VIDEO_FORMAT_SECAM: 86 ADD ("PAL", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
86 ADD ("SECAM", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 87 break;
87 break; 88 case SEQ_VIDEO_FORMAT_NTSC:
88 case SEQ_VIDEO_FORMAT_MAC: 89 ADD ("NTSC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
89 ADD ("MAC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM); 90 break;
90 break; 91 case SEQ_VIDEO_FORMAT_SECAM:
91 default: 92 ADD ("SECAM", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
92 break; 93 break;
93 } 94 case SEQ_VIDEO_FORMAT_MAC:
94 if ((info->sequence->flags & SEQ_FLAG_MPEG2) > 0) 95 ADD ("MAC", EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM);
95 ADD ("MPEG2", EXTRACTOR_METATYPE_FORMAT_VERSION); 96 break;
96 else 97 default:
97 ADD ("MPEG1", EXTRACTOR_METATYPE_FORMAT_VERSION); 98 break;
98 } 99 }
99 if (info->gop != NULL) 100 if ((info->sequence->flags & SEQ_FLAG_MPEG2) > 0)
100 { 101 ADD ("MPEG2", EXTRACTOR_METATYPE_FORMAT_VERSION);
101 /* this usually does not work yet, since gop's are not 102 else
102 often at the beginning of the stream (and we 103 ADD ("MPEG1", EXTRACTOR_METATYPE_FORMAT_VERSION);
103 don't iterate over the stream hoping to find one). 104 finished &= ~2;
104 Hence we usually don't get the size. Not sure how 105 break;
105 to *efficiently* get the gop (without scanning 106 case STATE_GOP:
106 through the entire file) */ 107 if ( (NULL != info->gop) &&
107 snprintf (format, 108 (0 != info->gop->pictures) )
108 sizeof(format), "%u:%u:%u (%u frames)", 109 {
109 info->gop->hours, 110 snprintf (format,
110 info->gop->minutes, info->gop->seconds, info->gop->pictures); 111 sizeof(format),
111 ADD (format, EXTRACTOR_METATYPE_DURATION); 112 "%u:%u:%u (%u frames)",
113 info->gop->hours,
114 info->gop->minutes, info->gop->seconds, info->gop->pictures);
115 ADD (format, EXTRACTOR_METATYPE_DURATION);
116 finished &= ~1;
117 }
118 break;
119 case STATE_SLICE:
120 break;
121 case STATE_END:
122 break;
123 case STATE_INVALID:
124 goto EXIT;
125 default:
126 break;
127 }
112 } 128 }
113 EXIT: 129 EXIT:
114 mpeg2_close (handle); 130 mpeg2_close (handle);
115 return ret;
116} 131}
132
133/* end of mpeg_extractor.c */
diff --git a/src/plugins/test_mpeg.c b/src/plugins/test_mpeg.c
new file mode 100644
index 0000000..88d8bd6
--- /dev/null
+++ b/src/plugins/test_mpeg.c
@@ -0,0 +1,88 @@
1/*
2 This file is part of libextractor.
3 (C) 2012 Vidyut Samanta and Christian Grothoff
4
5 libextractor is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
9
10 libextractor is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with libextractor; see the file COPYING. If not, write to the
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
19*/
20/**
21 * @file plugins/test_mpeg.c
22 * @brief testcase for mpeg plugin
23 * @author Christian Grothoff
24 */
25#include "platform.h"
26#include "test_lib.h"
27
28
29
30/**
31 * Main function for the MPEG testcase.
32 *
33 * @param argc number of arguments (ignored)
34 * @param argv arguments (ignored)
35 * @return 0 on success
36 */
37int
38main (int argc, char *argv[])
39{
40 struct SolutionData melt_sol[] =
41 {
42 {
43 EXTRACTOR_METATYPE_MIMETYPE,
44 EXTRACTOR_METAFORMAT_UTF8,
45 "text/plain",
46 "video/mpeg",
47 strlen ("video/mpeg") + 1,
48 0
49 },
50 {
51 EXTRACTOR_METATYPE_IMAGE_DIMENSIONS,
52 EXTRACTOR_METAFORMAT_UTF8,
53 "text/plain",
54 "320x208",
55 strlen ("320x208") + 1,
56 0
57 },
58 {
59 EXTRACTOR_METATYPE_FORMAT_VERSION,
60 EXTRACTOR_METAFORMAT_UTF8,
61 "text/plain",
62 "MPEG1",
63 strlen ("MPEG1") + 1,
64 0
65 },
66#if 0
67 /* GOP is somehow not working for this example */
68 {
69 EXTRACTOR_METATYPE_DURATION,
70 EXTRACTOR_METAFORMAT_UTF8,
71 "text/plain",
72 "0:0:0 (0 frames)", /* FIXME: this is obviously the wrong answer */
73 strlen ("0:0:0 (0 frames)") + 1,
74 0
75 },
76#endif
77 { 0, 0, NULL, NULL, 0, -1 }
78 };
79 struct ProblemSet ps[] =
80 {
81 { "testdata/mpeg_melt.mpg",
82 melt_sol },
83 { NULL, NULL }
84 };
85 return ET_main ("mpeg", ps);
86}
87
88/* end of test_mpeg.c */
diff --git a/src/plugins/testdata/mpeg_melt.mpg b/src/plugins/testdata/mpeg_melt.mpg
new file mode 100644
index 0000000..7bbfc11
--- /dev/null
+++ b/src/plugins/testdata/mpeg_melt.mpg
Binary files differ