libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

mpeg_extractor.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2004, 2005, 2006, 2009, 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., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19  */
20 
21 /**
22  * @file plugins/mpeg_extractor.c
23  * @brief plugin to support MPEG files
24  * @author Christian Grothoff
25  */
26 #include "platform.h"
27 #include "extractor.h"
28 #include <mpeg2dec/mpeg2.h>
29 
30 
31 /**
32  * Give meta data to extractor.
33  *
34  * @param t type of the meta data
35  * @param s meta data value in utf8 format
36  */
37 #define ADD(s,t) do { if (0 != ec->proc (ec->cls, "mpeg", t, \
38  EXTRACTOR_METAFORMAT_UTF8, \
39  "text/plain", s, strlen (s) \
40  + 1)) goto EXIT; \
41 } while (0)
42 
43 
44 /**
45  * Main entry method for the 'video/mpeg' extraction plugin.
46  *
47  * @param ec extraction context provided to the plugin
48  */
49 void
51 {
52  mpeg2dec_t *handle;
53  const mpeg2_info_t *info;
54  void *buf;
55  ssize_t avail;
56  mpeg2_state_t state;
57  char format[256];
58  char lformat[256];
59  char gop_format[256];
60  int have_gop;
61  uint64_t fsize;
62  unsigned int fail_count;
63  int did_seek;
64  int fmt1;
65  int fmt2;
66  int mime;
67  int fpal;
68  int fntsc;
69  int fsecam;
70  int fmac;
71 
72  if (NULL == (handle = mpeg2_init ()))
73  return;
74  if (NULL == (info = mpeg2_info (handle)))
75  {
76  mpeg2_close (handle);
77  return;
78  }
79  fsize = ec->get_size (ec->cls);
80  buf = NULL;
81  have_gop = 0;
82  fail_count = 0;
83  did_seek = 0;
84  fmt1 = 0;
85  fmt2 = 0;
86  mime = 0;
87  fpal = 0;
88  fntsc = 0;
89  fsecam = 0;
90  fmac = 0;
91  lformat[0] = '\0';
92  while (1)
93  {
94  state = mpeg2_parse (handle);
95  switch (state)
96  {
97  case STATE_BUFFER:
98  if (fail_count > 16)
99  goto EXIT; /* do not read large non-mpeg files */
100  fail_count++;
101  if (0 >= (avail = ec->read (ec->cls,
102  &buf,
103  16 * 1024)))
104  goto EXIT;
105  mpeg2_buffer (handle, buf, buf + avail);
106  break;
107  case STATE_SEQUENCE:
108  fail_count = 0;
109  format[0] = fsize;
110  format[0]++;
111  if (0 == mime)
112  {
113  mime = 1;
114  ADD ("video/mpeg", EXTRACTOR_METATYPE_MIMETYPE);
115  }
116  snprintf (format,
117  sizeof(format), "%ux%u",
118  info->sequence->width, info->sequence->height);
119  if (0 != strcmp (lformat,
120  format))
121  {
122  strcpy (lformat,
123  format);
125  }
126  switch (info->sequence->flags & SEQ_VIDEO_FORMAT_UNSPECIFIED)
127  {
128  case SEQ_VIDEO_FORMAT_PAL:
129  if (0 == fpal)
130  {
131  fpal = 1;
133  }
134  break;
135  case SEQ_VIDEO_FORMAT_NTSC:
136  if (0 == fntsc)
137  {
138  fntsc = 1;
140  }
141  break;
142  case SEQ_VIDEO_FORMAT_SECAM:
143  if (0 == fsecam)
144  {
145  fsecam = 1;
147  }
148  break;
149  case SEQ_VIDEO_FORMAT_MAC:
150  if (0 == fmac)
151  {
152  fmac = 1;
154  }
155  break;
156  default:
157  break;
158  }
159  if ((info->sequence->flags & SEQ_FLAG_MPEG2) > 0)
160  {
161  if (0 == fmt1)
162  {
163  fmt1 = 1;
165  }
166  }
167  else
168  {
169  if (0 == fmt2)
170  {
171  fmt2 = 1;
173  }
174  }
175  if ( (0 == did_seek) &&
176  (fsize != -1) &&
177  (fsize > 1024 * 256 * 2) )
178  {
179  /* skip to the end of the mpeg for speed */
180  did_seek = 1;
181  ec->seek (ec->cls,
182  fsize - 256 * 1024,
183  SEEK_SET);
184  }
185  break;
186  case STATE_GOP:
187  fail_count = 0;
188  if ( (NULL != info->gop) &&
189  (0 != info->gop->pictures) )
190  {
191  snprintf (gop_format,
192  sizeof (gop_format),
193  "%02u:%02u:%02u (%u frames)",
194  info->gop->hours,
195  info->gop->minutes,
196  info->gop->seconds,
197  info->gop->pictures);
198  have_gop = 1;
199  }
200  break;
201  case STATE_SLICE:
202  fail_count = 0;
203  break;
204  case STATE_END:
205  fail_count = 0;
206  break;
207  case STATE_INVALID:
208  goto EXIT;
209  default:
210  break;
211  }
212  }
213 EXIT:
214  if (1 == have_gop)
215  ADD (gop_format, EXTRACTOR_METATYPE_DURATION);
216  mpeg2_close (handle);
217 }
218 
219 
220 /* end of mpeg_extractor.c */
#define NULL
Definition: getopt1.c:60
@ EXTRACTOR_METATYPE_BROADCAST_TELEVISION_SYSTEM
Definition: extractor.h:291
@ EXTRACTOR_METATYPE_FORMAT_VERSION
Definition: extractor.h:191
@ EXTRACTOR_METATYPE_MIMETYPE
Definition: extractor.h:129
@ EXTRACTOR_METATYPE_IMAGE_DIMENSIONS
Definition: extractor.h:257
@ EXTRACTOR_METATYPE_DURATION
Definition: extractor.h:277
void EXTRACTOR_mpeg_extract_method(struct EXTRACTOR_ExtractContext *ec)
#define ADD(s, t)
plaform specifics
int64_t(* seek)(void *cls, int64_t pos, int whence)
Definition: extractor.h:509
uint64_t(* get_size)(void *cls)
Definition: extractor.h:520
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494