mxfinfo 0.0.3.6 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|