aboutsummaryrefslogtreecommitdiff
path: root/src/plugins/mpeg_extractor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/mpeg_extractor.c')
-rw-r--r--src/plugins/mpeg_extractor.c171
1 files changed, 94 insertions, 77 deletions
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 */