mxfinfo 0.0.3.6 → 0.0.4
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +15 -0
- data/.gitignore +3 -0
- data/Gemfile +0 -6
- data/LICENSE +3 -2
- data/README.md +3 -3
- data/Rakefile +3 -5
- data/ext/mxfinfo/avid_mxf_info.c +1507 -0
- data/ext/mxfinfo/avid_mxf_info.h +194 -0
- data/ext/mxfinfo/extconf.rb +12 -0
- data/ext/mxfinfo/mxfinfo.c +313 -0
- data/lib/mxfinfo/version.rb +2 -2
- data/lib/mxfinfo.rb +24 -117
- data/mxfinfo.gemspec +13 -10
- data/spec/info_object_spec.rb +42 -0
- data/spec/mxfinfo_spec.rb +20 -70
- data/spec/spec_helper.rb +0 -18
- metadata +49 -48
- data/lib/mxfinfo/attr_readers.rb +0 -61
- data/lib/mxfinfo/string.rb +0 -25
- data/spec/alert_error_spec.rb +0 -10
- data/spec/fixtures/ALERT01.ERROR.info +0 -8
- data/spec/fixtures/IMG_0395.MOV.A14DC7130D.mxf.info +0 -44
- data/spec/fixtures/center_smooth.info +0 -29
- data/spec/fixtures/color_correction.info +0 -29
- data/spec/fixtures/crystal.info +0 -29
- data/spec/fixtures/flip-flop.info +0 -29
- data/spec/fixtures/fluidblur.info +0 -29
- data/spec/fixtures/left_box.info +0 -29
- data/spec/fixtures/luma_key.info +0 -29
- data/spec/fixtures/mosaic_effect.info +0 -29
- data/spec/fixtures/stabilize.info +0 -29
- data/spec/fixtures/timecode_burn-in.info +0 -29
- data/spec/img_0395.mov.a14dc7130d_spec.rb +0 -116
- data/spec/render_files_spec.rb +0 -25
@@ -0,0 +1,194 @@
|
|
1
|
+
/*
|
2
|
+
* Parse metadata from an Avid MXF file
|
3
|
+
*
|
4
|
+
* Copyright (C) 2008, British Broadcasting Corporation
|
5
|
+
* All Rights Reserved.
|
6
|
+
*
|
7
|
+
* Author: Philip de Nier
|
8
|
+
*
|
9
|
+
* Redistribution and use in source and binary forms, with or without
|
10
|
+
* modification, are permitted provided that the following conditions are met:
|
11
|
+
*
|
12
|
+
* * Redistributions of source code must retain the above copyright notice,
|
13
|
+
* this list of conditions and the following disclaimer.
|
14
|
+
* * Redistributions in binary form must reproduce the above copyright
|
15
|
+
* notice, this list of conditions and the following disclaimer in the
|
16
|
+
* documentation and/or other materials provided with the distribution.
|
17
|
+
* * Neither the name of the British Broadcasting Corporation nor the names
|
18
|
+
* of its contributors may be used to endorse or promote products derived
|
19
|
+
* from this software without specific prior written permission.
|
20
|
+
*
|
21
|
+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
22
|
+
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
23
|
+
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
24
|
+
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
25
|
+
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
26
|
+
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
27
|
+
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
28
|
+
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
29
|
+
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
30
|
+
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
31
|
+
* POSSIBILITY OF SUCH DAMAGE.
|
32
|
+
*/
|
33
|
+
|
34
|
+
#ifndef __AVID_MXF_INFO_H__
|
35
|
+
#define __AVID_MXF_INFO_H__
|
36
|
+
|
37
|
+
|
38
|
+
#ifdef __cplusplus
|
39
|
+
extern "C"
|
40
|
+
{
|
41
|
+
#endif
|
42
|
+
|
43
|
+
|
44
|
+
#include <mxf/mxf_types.h>
|
45
|
+
|
46
|
+
|
47
|
+
/* Note: keep get_essence_type_string() in sync when changes are made here */
|
48
|
+
typedef enum
|
49
|
+
{
|
50
|
+
UNKNOWN_ESSENCE_TYPE = 0,
|
51
|
+
MPEG_30_ESSENCE_TYPE,
|
52
|
+
MPEG_40_ESSENCE_TYPE,
|
53
|
+
MPEG_50_ESSENCE_TYPE,
|
54
|
+
DV_25_411_ESSENCE_TYPE,
|
55
|
+
DV_25_420_ESSENCE_TYPE,
|
56
|
+
DV_50_ESSENCE_TYPE,
|
57
|
+
DV_100_ESSENCE_TYPE,
|
58
|
+
MJPEG_20_1_ESSENCE_TYPE,
|
59
|
+
MJPEG_2_1_S_ESSENCE_TYPE,
|
60
|
+
MJPEG_4_1_S_ESSENCE_TYPE,
|
61
|
+
MJPEG_15_1_S_ESSENCE_TYPE,
|
62
|
+
MJPEG_10_1_ESSENCE_TYPE,
|
63
|
+
MJPEG_10_1_M_ESSENCE_TYPE,
|
64
|
+
MJPEG_4_1_M_ESSENCE_TYPE,
|
65
|
+
MJPEG_3_1_ESSENCE_TYPE,
|
66
|
+
MJPEG_2_1_ESSENCE_TYPE,
|
67
|
+
UNC_1_1_ESSENCE_TYPE,
|
68
|
+
UNC_1_1_10B_ESSENCE_TYPE,
|
69
|
+
MJPEG_35_1_P_ESSENCE_TYPE,
|
70
|
+
MJPEG_28_1_P_ESSENCE_TYPE,
|
71
|
+
MJPEG_14_1_P_ESSENCE_TYPE,
|
72
|
+
MJPEG_3_1_P_ESSENCE_TYPE,
|
73
|
+
MJPEG_2_1_P_ESSENCE_TYPE,
|
74
|
+
MJPEG_3_1_M_ESSENCE_TYPE,
|
75
|
+
MJPEG_8_1_M_ESSENCE_TYPE,
|
76
|
+
DNXHD_1235_ESSENCE_TYPE,
|
77
|
+
DNXHD_1237_ESSENCE_TYPE,
|
78
|
+
DNXHD_1238_ESSENCE_TYPE,
|
79
|
+
DNXHD_1241_ESSENCE_TYPE,
|
80
|
+
DNXHD_1242_ESSENCE_TYPE,
|
81
|
+
DNXHD_1243_ESSENCE_TYPE,
|
82
|
+
DNXHD_1250_ESSENCE_TYPE,
|
83
|
+
DNXHD_1251_ESSENCE_TYPE,
|
84
|
+
DNXHD_1252_ESSENCE_TYPE,
|
85
|
+
DNXHD_1253_ESSENCE_TYPE,
|
86
|
+
MPEG4_ESSENCE_TYPE,
|
87
|
+
XDCAM_HD_ESSENCE_TYPE,
|
88
|
+
AVCINTRA_100_ESSENCE_TYPE,
|
89
|
+
AVCINTRA_50_ESSENCE_TYPE,
|
90
|
+
PCM_ESSENCE_TYPE
|
91
|
+
} AvidEssenceType;
|
92
|
+
|
93
|
+
typedef enum
|
94
|
+
{
|
95
|
+
UNKNOWN_PHYS_TYPE = 0,
|
96
|
+
TAPE_PHYS_TYPE,
|
97
|
+
IMPORT_PHYS_TYPE,
|
98
|
+
RECORDING_PHYS_TYPE
|
99
|
+
} AvidPhysicalPackageType;
|
100
|
+
|
101
|
+
typedef enum
|
102
|
+
{
|
103
|
+
FULL_FRAME_FRAME_LAYOUT = 0,
|
104
|
+
SEPARATE_FIELDS_FRAME_LAYOUT,
|
105
|
+
SINGLE_FIELD_FRAME_LAYOUT,
|
106
|
+
MIXED_FIELD_FRAME_LAYOUT,
|
107
|
+
SEGMENTED_FRAME_FRAME_LAYOUT,
|
108
|
+
} AvidFrameLayout;
|
109
|
+
|
110
|
+
typedef struct
|
111
|
+
{
|
112
|
+
char *name;
|
113
|
+
char *value;
|
114
|
+
} AvidNameValuePair;
|
115
|
+
|
116
|
+
typedef struct
|
117
|
+
{
|
118
|
+
char *name;
|
119
|
+
char *value;
|
120
|
+
AvidNameValuePair *attributes;
|
121
|
+
int numAttributes;
|
122
|
+
} AvidTaggedValue;
|
123
|
+
|
124
|
+
typedef struct
|
125
|
+
{
|
126
|
+
/* clip info */
|
127
|
+
char *clipName;
|
128
|
+
char *projectName;
|
129
|
+
mxfTimestamp clipCreated;
|
130
|
+
mxfRational projectEditRate;
|
131
|
+
int64_t clipDuration;
|
132
|
+
mxfUMID materialPackageUID;
|
133
|
+
AvidTaggedValue *userComments;
|
134
|
+
int numUserComments;
|
135
|
+
AvidTaggedValue *materialPackageAttributes;
|
136
|
+
int numMaterialPackageAttributes;
|
137
|
+
int numVideoTracks;
|
138
|
+
int numAudioTracks;
|
139
|
+
char *tracksString;
|
140
|
+
|
141
|
+
/* track info */
|
142
|
+
uint32_t trackNumber;
|
143
|
+
int isVideo;
|
144
|
+
mxfRational editRate;
|
145
|
+
int64_t trackDuration;
|
146
|
+
int64_t segmentDuration;
|
147
|
+
int64_t segmentOffset;
|
148
|
+
int64_t startTimecode;
|
149
|
+
|
150
|
+
/* file essence info */
|
151
|
+
AvidEssenceType essenceType;
|
152
|
+
mxfUMID fileSourcePackageUID;
|
153
|
+
mxfUL essenceContainerLabel;
|
154
|
+
|
155
|
+
/* picture info */
|
156
|
+
mxfUL pictureCodingLabel;
|
157
|
+
uint8_t frameLayout;
|
158
|
+
mxfRational aspectRatio;
|
159
|
+
uint32_t storedWidth;
|
160
|
+
uint32_t storedHeight;
|
161
|
+
uint32_t displayWidth;
|
162
|
+
uint32_t displayHeight;
|
163
|
+
|
164
|
+
/* sound info */
|
165
|
+
mxfRational audioSamplingRate;
|
166
|
+
uint32_t channelCount;
|
167
|
+
uint32_t quantizationBits;
|
168
|
+
|
169
|
+
/* physical source info */
|
170
|
+
char *physicalPackageName;
|
171
|
+
mxfUMID physicalSourcePackageUID;
|
172
|
+
AvidPhysicalPackageType physicalPackageType;
|
173
|
+
char *physicalPackageLocator;
|
174
|
+
|
175
|
+
} AvidMXFInfo;
|
176
|
+
|
177
|
+
|
178
|
+
|
179
|
+
int ami_read_info(const char *filename, AvidMXFInfo *info, int printDebugError);
|
180
|
+
|
181
|
+
void ami_free_info(AvidMXFInfo *info);
|
182
|
+
|
183
|
+
void ami_print_info(AvidMXFInfo *info);
|
184
|
+
/* TODO: add function to print machine readable info e.g. newline delimited fields */
|
185
|
+
|
186
|
+
const char* get_essence_type_string(AvidEssenceType essenceType, mxfRational editRate);
|
187
|
+
|
188
|
+
#ifdef __cplusplus
|
189
|
+
}
|
190
|
+
#endif
|
191
|
+
|
192
|
+
|
193
|
+
#endif
|
194
|
+
|
@@ -0,0 +1,313 @@
|
|
1
|
+
#include <time.h>
|
2
|
+
#include <ruby.h>
|
3
|
+
#include "avid_mxf_info.h"
|
4
|
+
|
5
|
+
/* Helpers. */
|
6
|
+
|
7
|
+
static
|
8
|
+
VALUE rb_time_from_mxf_timestamp(mxfTimestamp *ts)
|
9
|
+
{
|
10
|
+
/*
|
11
|
+
* NOTE: This is probably not thread-safe, since struct tm*
|
12
|
+
* returned by localtime is shared static.
|
13
|
+
*/
|
14
|
+
time_t t;
|
15
|
+
time(&t);
|
16
|
+
struct tm *tmts;
|
17
|
+
tmts = localtime(&t);
|
18
|
+
|
19
|
+
tmts->tm_year = (int) ts->year - 1900;
|
20
|
+
tmts->tm_mon = (int) ts->month - 1;
|
21
|
+
tmts->tm_mday = (int) ts->day;
|
22
|
+
tmts->tm_hour = (int) ts->hour;
|
23
|
+
tmts->tm_min = (int) ts->min;
|
24
|
+
tmts->tm_sec = (int) ts->sec;
|
25
|
+
|
26
|
+
return rb_time_new(mktime(tmts), ts->qmsec);
|
27
|
+
}
|
28
|
+
|
29
|
+
static
|
30
|
+
VALUE rb_str_from_label(const unsigned char *lbl, int len)
|
31
|
+
{
|
32
|
+
char hex[len * 2 + 1];
|
33
|
+
for(int i = 0; i < len; i++)
|
34
|
+
{
|
35
|
+
sprintf(&hex[i * 2], "%02x", lbl[i]);
|
36
|
+
}
|
37
|
+
hex[len * 2 + 1] = '\0';
|
38
|
+
return rb_str_new2(hex);
|
39
|
+
}
|
40
|
+
|
41
|
+
/* Some macros. */
|
42
|
+
|
43
|
+
#define CIO_GENERIC_GETTER(cast, name, attr) \
|
44
|
+
static \
|
45
|
+
VALUE cio_get_##name (VALUE self) \
|
46
|
+
{ \
|
47
|
+
AvidMXFInfo *info; \
|
48
|
+
Data_Get_Struct(self, AvidMXFInfo, info); \
|
49
|
+
return cast (info-> attr ); \
|
50
|
+
}
|
51
|
+
|
52
|
+
#define CIO_STRING_GETTER(name, attr) \
|
53
|
+
static \
|
54
|
+
VALUE cio_get_##name (VALUE self) \
|
55
|
+
{ \
|
56
|
+
AvidMXFInfo *info; \
|
57
|
+
Data_Get_Struct(self, AvidMXFInfo, info); \
|
58
|
+
return ((info-> attr ) != NULL) ? rb_str_new2(info-> attr ) : Qnil; \
|
59
|
+
}
|
60
|
+
|
61
|
+
#define CIO_LABEL_GETTER(name, attr, len) \
|
62
|
+
static \
|
63
|
+
VALUE cio_get_##name (VALUE self) \
|
64
|
+
{ \
|
65
|
+
AvidMXFInfo *info; \
|
66
|
+
Data_Get_Struct(self, AvidMXFInfo, info); \
|
67
|
+
return rb_str_from_label((unsigned char*) &( info-> attr ), len ); \
|
68
|
+
}
|
69
|
+
|
70
|
+
#define CIO_RATIONAL_GETTER(name, attr) \
|
71
|
+
static \
|
72
|
+
VALUE cio_get_##name (VALUE self) \
|
73
|
+
{ \
|
74
|
+
AvidMXFInfo *info; \
|
75
|
+
Data_Get_Struct(self, AvidMXFInfo, info); \
|
76
|
+
return rb_rational_new(INT2FIX((info-> attr ).numerator), \
|
77
|
+
INT2FIX((info-> attr ).denominator)); \
|
78
|
+
}
|
79
|
+
|
80
|
+
#define CIO_INT_GETTER(name, attr) CIO_GENERIC_GETTER(INT2FIX, name, attr)
|
81
|
+
#define CIO_UINT_GETTER(name, attr) CIO_GENERIC_GETTER(UINT2NUM, name, attr)
|
82
|
+
#define CIO_INT64_GETTER(name, attr) CIO_GENERIC_GETTER(LL2NUM, name, attr)
|
83
|
+
|
84
|
+
/* Ruby API. */
|
85
|
+
|
86
|
+
VALUE m_mxfinfo = Qnil;
|
87
|
+
VALUE c_infoobject = Qnil;
|
88
|
+
|
89
|
+
static
|
90
|
+
void cio_free(void *ptr) {
|
91
|
+
ami_free_info(ptr);
|
92
|
+
}
|
93
|
+
|
94
|
+
static
|
95
|
+
VALUE cio_new(VALUE class, VALUE path)
|
96
|
+
{
|
97
|
+
Check_Type(path, T_STRING);
|
98
|
+
const char *fn = StringValuePtr(path);
|
99
|
+
|
100
|
+
AvidMXFInfo *info = ALLOC(AvidMXFInfo);
|
101
|
+
|
102
|
+
int result = ami_read_info(fn, info, 1);
|
103
|
+
|
104
|
+
if(result != 0)
|
105
|
+
{
|
106
|
+
ami_free_info(info);
|
107
|
+
|
108
|
+
switch(result)
|
109
|
+
{
|
110
|
+
case -2:
|
111
|
+
rb_raise(rb_eIOError, "Failed to open file.");
|
112
|
+
break;
|
113
|
+
case -3:
|
114
|
+
rb_raise(rb_eIOError, "Failed to read header partition.");
|
115
|
+
break;
|
116
|
+
case -4:
|
117
|
+
rb_raise(rb_eStandardError, "File is not OP-Atom.");
|
118
|
+
break;
|
119
|
+
case -1:
|
120
|
+
default:
|
121
|
+
rb_raise(rb_eStandardError, "Failed to read info.");
|
122
|
+
break;
|
123
|
+
}
|
124
|
+
|
125
|
+
return Qnil;
|
126
|
+
}
|
127
|
+
else
|
128
|
+
{
|
129
|
+
VALUE tdata = Data_Wrap_Struct(class, 0, cio_free, info);
|
130
|
+
return tdata;
|
131
|
+
}
|
132
|
+
}
|
133
|
+
|
134
|
+
/* Simple getters. */
|
135
|
+
|
136
|
+
CIO_STRING_GETTER(clip_name, clipName)
|
137
|
+
CIO_STRING_GETTER(project_name, projectName)
|
138
|
+
CIO_RATIONAL_GETTER(project_edit_rate, projectEditRate)
|
139
|
+
CIO_INT64_GETTER(clip_duration, clipDuration)
|
140
|
+
CIO_LABEL_GETTER(material_package_uid, materialPackageUID, 32)
|
141
|
+
CIO_INT_GETTER(num_video_tracks, numVideoTracks)
|
142
|
+
CIO_INT_GETTER(num_audio_tracks, numAudioTracks)
|
143
|
+
CIO_STRING_GETTER(tracks_string, tracksString)
|
144
|
+
CIO_UINT_GETTER(track_number, trackNumber)
|
145
|
+
CIO_RATIONAL_GETTER(edit_rate, editRate)
|
146
|
+
CIO_INT64_GETTER(track_duration, trackDuration)
|
147
|
+
CIO_INT64_GETTER(segment_duration, segmentDuration)
|
148
|
+
CIO_INT64_GETTER(segment_offset, segmentOffset)
|
149
|
+
CIO_INT64_GETTER(start_timecode, startTimecode)
|
150
|
+
CIO_LABEL_GETTER(essence_container_label, essenceContainerLabel, 16)
|
151
|
+
CIO_LABEL_GETTER(file_source_package_uid, fileSourcePackageUID, 32)
|
152
|
+
CIO_LABEL_GETTER(picture_coding_label, pictureCodingLabel, 16)
|
153
|
+
CIO_UINT_GETTER(frame_layout, frameLayout)
|
154
|
+
CIO_UINT_GETTER(stored_width, storedWidth)
|
155
|
+
CIO_UINT_GETTER(stored_height, storedHeight)
|
156
|
+
CIO_UINT_GETTER(display_width, displayWidth)
|
157
|
+
CIO_UINT_GETTER(display_height, displayHeight)
|
158
|
+
CIO_RATIONAL_GETTER(audio_sampling_rate, audioSamplingRate)
|
159
|
+
CIO_UINT_GETTER(channel_count, channelCount)
|
160
|
+
CIO_UINT_GETTER(quantization_bits, quantizationBits)
|
161
|
+
CIO_STRING_GETTER(physical_package_name, physicalPackageName)
|
162
|
+
CIO_LABEL_GETTER(physical_source_package_uid, physicalSourcePackageUID, 32)
|
163
|
+
CIO_STRING_GETTER(physical_package_locator, physicalPackageLocator)
|
164
|
+
/* ... */
|
165
|
+
|
166
|
+
/* Random attributes that need special treatment. */
|
167
|
+
|
168
|
+
static
|
169
|
+
VALUE cio_get_clip_created(VALUE self)
|
170
|
+
{
|
171
|
+
AvidMXFInfo *info;
|
172
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
173
|
+
return rb_time_from_mxf_timestamp(&info->clipCreated);
|
174
|
+
}
|
175
|
+
|
176
|
+
/*
|
177
|
+
* Left that in for reference (array creation).
|
178
|
+
static
|
179
|
+
VALUE cio_get_material_package_uid(VALUE self)
|
180
|
+
{
|
181
|
+
AvidMXFInfo *info;
|
182
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
183
|
+
|
184
|
+
unsigned char *uid = (unsigned char*) &info->materialPackageUID;
|
185
|
+
|
186
|
+
VALUE ary = rb_ary_new2(32);
|
187
|
+
for(unsigned int i = 0; i < 32; i++)
|
188
|
+
{
|
189
|
+
rb_ary_store(ary, i, CHR2FIX(uid[i]));
|
190
|
+
}
|
191
|
+
|
192
|
+
return ary;
|
193
|
+
}
|
194
|
+
*/
|
195
|
+
|
196
|
+
static
|
197
|
+
VALUE cio_get_is_video(VALUE self)
|
198
|
+
{
|
199
|
+
AvidMXFInfo *info;
|
200
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
201
|
+
return info->isVideo ? Qtrue : Qfalse;
|
202
|
+
}
|
203
|
+
|
204
|
+
static
|
205
|
+
VALUE cio_get_essence_type(VALUE self)
|
206
|
+
{
|
207
|
+
AvidMXFInfo *info;
|
208
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
209
|
+
return rb_str_new2(get_essence_type_string(info->essenceType, info->projectEditRate));
|
210
|
+
}
|
211
|
+
|
212
|
+
static
|
213
|
+
VALUE cio_get_aspect_ratio(VALUE self)
|
214
|
+
{
|
215
|
+
AvidMXFInfo *info;
|
216
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
217
|
+
if(info->isVideo && info->aspectRatio.denominator != 0)
|
218
|
+
{
|
219
|
+
return rb_rational_new(INT2FIX(info->aspectRatio.numerator),
|
220
|
+
INT2FIX(info->aspectRatio.denominator));
|
221
|
+
}
|
222
|
+
else
|
223
|
+
{
|
224
|
+
return Qnil;
|
225
|
+
}
|
226
|
+
}
|
227
|
+
|
228
|
+
static
|
229
|
+
VALUE cio_get_physical_package_type(VALUE self)
|
230
|
+
{
|
231
|
+
AvidMXFInfo *info;
|
232
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
233
|
+
|
234
|
+
VALUE ret = Qnil;
|
235
|
+
switch (info->physicalPackageType)
|
236
|
+
{
|
237
|
+
case TAPE_PHYS_TYPE:
|
238
|
+
ret = ID2SYM(rb_intern("tape"));
|
239
|
+
break;
|
240
|
+
case IMPORT_PHYS_TYPE:
|
241
|
+
ret = ID2SYM(rb_intern("import"));
|
242
|
+
break;
|
243
|
+
case RECORDING_PHYS_TYPE:
|
244
|
+
ret = ID2SYM(rb_intern("recording"));
|
245
|
+
break;
|
246
|
+
case UNKNOWN_PHYS_TYPE:
|
247
|
+
default:
|
248
|
+
ret = ID2SYM(rb_intern("unknown"));
|
249
|
+
break;
|
250
|
+
}
|
251
|
+
|
252
|
+
return ret;
|
253
|
+
}
|
254
|
+
|
255
|
+
static
|
256
|
+
VALUE cio_get_clip_track_string(VALUE self)
|
257
|
+
{
|
258
|
+
AvidMXFInfo *info;
|
259
|
+
Data_Get_Struct(self, AvidMXFInfo, info);
|
260
|
+
|
261
|
+
return rb_str_new2((info->tracksString == NULL) ? "" : info->tracksString);
|
262
|
+
}
|
263
|
+
|
264
|
+
/* Module init. */
|
265
|
+
|
266
|
+
void Init_mxfinfo()
|
267
|
+
{
|
268
|
+
m_mxfinfo = rb_define_module("MXFInfo");
|
269
|
+
|
270
|
+
c_infoobject = rb_define_class_under(m_mxfinfo, "InfoObject", rb_cObject);
|
271
|
+
rb_define_singleton_method(c_infoobject, "new", cio_new, 1);
|
272
|
+
|
273
|
+
rb_define_method(c_infoobject, "clip_name", cio_get_clip_name, 0);
|
274
|
+
rb_define_method(c_infoobject, "project_name", cio_get_project_name, 0);
|
275
|
+
rb_define_method(c_infoobject, "clip_created", cio_get_clip_created, 0);
|
276
|
+
rb_define_method(c_infoobject, "project_edit_rate", cio_get_project_edit_rate, 0);
|
277
|
+
rb_define_method(c_infoobject, "clip_duration", cio_get_clip_duration, 0);
|
278
|
+
rb_define_method(c_infoobject, "material_package_uid", cio_get_material_package_uid, 0);
|
279
|
+
|
280
|
+
/* AvidTaggedValue *userComments */
|
281
|
+
/* int numUserComments */
|
282
|
+
/* AvidTaggedValue *materialPackageAttributes */
|
283
|
+
/* int numMaterialPackageAttributes */
|
284
|
+
|
285
|
+
rb_define_method(c_infoobject, "num_video_tracks", cio_get_num_video_tracks, 0);
|
286
|
+
rb_define_method(c_infoobject, "num_audio_tracks", cio_get_num_audio_tracks, 0);
|
287
|
+
rb_define_method(c_infoobject, "tracks_string", cio_get_tracks_string, 0);
|
288
|
+
rb_define_method(c_infoobject, "track_number", cio_get_track_number, 0);
|
289
|
+
rb_define_method(c_infoobject, "is_video", cio_get_is_video, 0);
|
290
|
+
rb_define_method(c_infoobject, "edit_rate", cio_get_edit_rate, 0);
|
291
|
+
rb_define_method(c_infoobject, "track_duration", cio_get_track_duration, 0);
|
292
|
+
rb_define_method(c_infoobject, "segment_duration", cio_get_segment_duration, 0);
|
293
|
+
rb_define_method(c_infoobject, "segment_offset", cio_get_segment_offset, 0);
|
294
|
+
rb_define_method(c_infoobject, "start_timecode", cio_get_start_timecode, 0);
|
295
|
+
rb_define_method(c_infoobject, "essence_type", cio_get_essence_type, 0);
|
296
|
+
rb_define_method(c_infoobject, "essence_container_label", cio_get_essence_container_label, 0);
|
297
|
+
rb_define_method(c_infoobject, "file_source_package_uid", cio_get_file_source_package_uid, 0);
|
298
|
+
rb_define_method(c_infoobject, "picture_coding_label", cio_get_picture_coding_label, 0);
|
299
|
+
rb_define_method(c_infoobject, "frame_layout", cio_get_frame_layout, 0);
|
300
|
+
rb_define_method(c_infoobject, "aspect_ratio", cio_get_aspect_ratio, 0);
|
301
|
+
rb_define_method(c_infoobject, "stored_width", cio_get_stored_width, 0);
|
302
|
+
rb_define_method(c_infoobject, "stored_height", cio_get_stored_height, 0);
|
303
|
+
rb_define_method(c_infoobject, "display_width", cio_get_display_width, 0);
|
304
|
+
rb_define_method(c_infoobject, "display_height", cio_get_display_height, 0);
|
305
|
+
rb_define_method(c_infoobject, "audio_sampling_rate", cio_get_audio_sampling_rate, 0);
|
306
|
+
rb_define_method(c_infoobject, "channel_count", cio_get_channel_count, 0);
|
307
|
+
rb_define_method(c_infoobject, "quantization_bits", cio_get_quantization_bits, 0);
|
308
|
+
rb_define_method(c_infoobject, "physical_package_name", cio_get_physical_package_name, 0);
|
309
|
+
rb_define_method(c_infoobject, "physical_source_package_uid", cio_get_physical_source_package_uid, 0);
|
310
|
+
rb_define_method(c_infoobject, "physical_package_type", cio_get_physical_package_type, 0);
|
311
|
+
rb_define_method(c_infoobject, "physical_package_locator", cio_get_physical_package_locator, 0);
|
312
|
+
rb_define_method(c_infoobject, "clip_track_string", cio_get_clip_track_string, 0);
|
313
|
+
}
|
data/lib/mxfinfo/version.rb
CHANGED
@@ -1,3 +1,3 @@
|
|
1
|
-
|
2
|
-
VERSION =
|
1
|
+
module MXFInfo
|
2
|
+
VERSION = '0.0.4'
|
3
3
|
end
|
data/lib/mxfinfo.rb
CHANGED
@@ -1,130 +1,37 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require File.join(File.dirname(__FILE__),"mxfinfo/attr_readers")
|
4
|
-
require File.join(File.dirname(__FILE__),"mxfinfo/string")
|
5
|
-
|
6
|
-
class MXFinfo
|
7
|
-
extend Forwardable
|
8
|
-
# We assume it's in the path of the user
|
9
|
-
@@binary = 'avidmxfinfo'
|
10
|
-
|
11
|
-
# BINARY CHANGE
|
12
|
-
def self.binary; @@binary; end
|
13
|
-
def self.binary=(binary); @@binary = binary; end
|
1
|
+
require 'mxfinfo.so'
|
2
|
+
require 'mxfinfo/version.rb'
|
14
3
|
|
4
|
+
module MXFInfo
|
15
5
|
def self.scan(path)
|
16
|
-
|
17
|
-
end
|
18
|
-
|
19
|
-
def self.import(data)
|
20
|
-
InfoObject.new(data, false)
|
6
|
+
InfoObject.new path
|
21
7
|
end
|
22
8
|
|
23
9
|
class InfoObject
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
# RAW AVIDMXFINFO OUTPUT
|
38
|
-
def raw_data; @mxfinfo; end
|
39
|
-
|
40
|
-
# Attributes
|
41
|
-
def self.supported_attributes; @supported_attributes ||= []; end
|
42
|
-
|
43
|
-
def initialize(input, process = true)
|
44
|
-
if process
|
45
|
-
@filepath = File.absolute_path(input)
|
46
|
-
File.exists?(@filepath) ? @valid = true : @valid = false
|
47
|
-
@mxfinfo = mxfinfo if @valid
|
48
|
-
else
|
49
|
-
@valid = true
|
50
|
-
@mxfinfo = input
|
51
|
-
end
|
52
|
-
# Check if output contains error from binary
|
53
|
-
@mxfinfo.include?("ERROR") ? @valid = false : @valid = true
|
54
|
-
@mxfinfo.include?("Failed to open file") ? @valid = false : @valid = true
|
55
|
-
@mxfinfo.include?("mxf_disk_file_open_read") ? @valid = false : @valid = true
|
56
|
-
process_data if @valid
|
57
|
-
end
|
58
|
-
|
59
|
-
def valid?
|
60
|
-
@valid
|
61
|
-
end
|
62
|
-
|
63
|
-
mxfinfo_attr_reader :filename
|
64
|
-
mxfinfo_attr_reader :project_name
|
65
|
-
mxfinfo_attr_reader :clip_name
|
66
|
-
mxfinfo_date_reader :clip_created_at, "Clip Created"
|
67
|
-
mxfinfo_attr_reader :project_edit_rate
|
68
|
-
mxfinfo_attr_reader :clip_edit_rate
|
69
|
-
mxfinfo_duration_reader :clip_duration
|
70
|
-
|
71
|
-
mxfinfo_attr_reader :videotracks, "Clip Video Tracks"
|
72
|
-
def v_tracks; videotracks.to_i; end
|
73
|
-
alias_method :video_tracks, :v_tracks
|
74
|
-
|
75
|
-
mxfinfo_attr_reader :audiotracks, "Clip Audio Tracks"
|
76
|
-
def a_tracks; audiotracks.to_i; end
|
77
|
-
alias_method :audio_tracks, :a_tracks
|
78
|
-
|
79
|
-
mxfinfo_attr_reader :clip_track_string
|
80
|
-
mxfinfo_attr_reader :essence_type
|
81
|
-
mxfinfo_attr_reader :essence_label
|
82
|
-
|
83
|
-
mxfinfo_attr_reader :tracknumber, "Track Number"
|
84
|
-
def t_number; tracknumber.to_i; end
|
85
|
-
alias_method :track_number, :t_number
|
86
|
-
|
87
|
-
mxfinfo_attr_reader :edit_rate
|
88
|
-
mxfinfo_duration_reader :track_duration
|
89
|
-
mxfinfo_duration_reader :track_segment_duration
|
90
|
-
mxfinfo_duration_reader :track_segment_offset
|
91
|
-
mxfinfo_timecode_reader :start_timecode
|
92
|
-
mxfinfo_attr_reader :audio_sampling_rate
|
93
|
-
|
94
|
-
mxfinfo_attr_reader :channelcount, "Channel Count"
|
95
|
-
def c_count; channelcount.to_i; end
|
96
|
-
alias_method :channel_count, :c_count
|
97
|
-
|
98
|
-
mxfinfo_attr_reader :quantizationbits, "Quantization Bits"
|
99
|
-
def q_bits; quantizationbits.to_i; end
|
100
|
-
alias_method :quantization_bits, :q_bits
|
101
|
-
|
102
|
-
mxfinfo_attr_reader :unc_path
|
103
|
-
mxfinfo_attr_reader :material_package_uid
|
104
|
-
mxfinfo_attr_reader :file_package_uid
|
105
|
-
mxfinfo_attr_reader :physical_package_uid
|
106
|
-
mxfinfo_attr_reader :physical_package_type
|
107
|
-
mxfinfo_attr_reader :physical_package_name
|
108
|
-
mxfinfo_attr_reader :physical_package_locator
|
10
|
+
alias_method :videotracks, :num_video_tracks
|
11
|
+
alias_method :v_tracks, :num_video_tracks
|
12
|
+
alias_method :video_tracks, :num_video_tracks
|
13
|
+
alias_method :audiotracks, :num_audio_tracks
|
14
|
+
alias_method :audio_tracks, :num_audio_tracks
|
15
|
+
alias_method :a_tracks, :num_audio_tracks
|
16
|
+
alias_method :clip_created_at, :clip_created
|
17
|
+
alias_method :essence_label, :essence_container_label
|
18
|
+
alias_method :t_number, :track_number
|
19
|
+
alias_method :tracknumber, :track_number
|
20
|
+
alias_method :channelcount, :channel_count
|
21
|
+
alias_method :c_count, :channel_count
|
22
|
+
alias_method :file_package_uid, :file_source_package_uid
|
109
23
|
|
110
24
|
def render_file?
|
111
25
|
physical_package_name == "Precompute Source Mob"
|
112
26
|
end
|
113
27
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
def process_data
|
121
|
-
@processed_data = Hash.new
|
122
|
-
@mxfinfo.each_line do |line|
|
123
|
-
if line.include?("=")
|
124
|
-
key, value = line.split("=")[0], line.split("=")[1]
|
125
|
-
@processed_data[key.strip.gsub(/\s+/, "_").downcase] = value.strip
|
126
|
-
end
|
127
|
-
end
|
28
|
+
alias_method :essence_type_orig, :essence_type
|
29
|
+
def essence_type
|
30
|
+
result = self.send(:essence_type_orig)
|
31
|
+
if result.start_with?("DNxHD")
|
32
|
+
result.gsub!(/ \(\d+\)/, "")
|
128
33
|
end
|
34
|
+
result
|
35
|
+
end
|
129
36
|
end
|
130
37
|
end
|