rmovie 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,81 @@
1
+ #ifndef QP_MOVIE_H
2
+ #define QP_MOVIE_H
3
+
4
+ #include <ffmpeg/avcodec.h>
5
+ #include <ffmpeg/avformat.h>
6
+
7
+ #include "qp_util.h"
8
+ #include "qp_frame.h"
9
+
10
+ #define QP_FRAME_BASED 0
11
+ #define QP_TIME_BASED 1
12
+
13
+ typedef struct {
14
+ AVFormatContext *fmt_ctx;
15
+ AVCodecContext *codec_ctx[MAX_STREAMS];
16
+ int64_t last_pts;
17
+ int frame_number; /* only valid in time based movies */
18
+ int mode;
19
+ offset_t last_file_pos;
20
+
21
+ /* qp_export_movie context stuff */
22
+
23
+ /* Video buffer */
24
+ uint8_t *video_outbuf;
25
+ int video_outbuf_size;
26
+
27
+ /* Audio buffer */
28
+ int16_t *audio_samples;
29
+ unsigned int audio_samples_size;
30
+
31
+ uint8_t *audio_outbuf;
32
+ int audio_outbuf_size;
33
+ int audio_input_frame_size;
34
+
35
+ /* User defined. */
36
+ void* user_defined;
37
+
38
+ /* Hack for php until I fix it up to use 'user_defined' */
39
+ long udef_long;
40
+ } qp_movie_context;
41
+
42
+ void qp_free_movie_ctx(qp_movie_context *movie_ctx, qp_free_t free_func);
43
+ qp_movie_context* qp_alloc_movie_ctx();
44
+ int qp_open_movie_file(qp_movie_context *movie_ctx, const char* filename);
45
+
46
+ float qp_get_frame_rate(qp_movie_context *movie_ctx);
47
+ float qp_get_duration(qp_movie_context *movie_ctx);
48
+ long qp_get_frame_count(qp_movie_context *movie_ctx);
49
+ char* qp_get_file_name(qp_movie_context *movie_ctx);
50
+
51
+ /* mp3 metadata accessors */
52
+ char* qp_get_comment(qp_movie_context *movie_ctx);
53
+ char* qp_get_title(qp_movie_context *movie_ctx);
54
+ char* qp_get_author(qp_movie_context *movie_ctx);
55
+ char* qp_get_copyright(qp_movie_context *movie_ctx);
56
+ char* qp_get_album(qp_movie_context *movie_ctx);
57
+ char* qp_get_genre(qp_movie_context *movie_ctx);
58
+ int qp_get_year(qp_movie_context *movie_ctx);
59
+ int qp_get_track(qp_movie_context *movie_ctx);
60
+
61
+ int qp_get_movie_width(qp_movie_context *movie_ctx);
62
+ int qp_get_movie_height(qp_movie_context *movie_ctx);
63
+ long qp_get_current_frame_number(qp_movie_context *movie_ctx);
64
+ const char* qp_get_movie_pixel_format_name(qp_movie_context *movie_ctx);
65
+ int qp_get_bit_rate(qp_movie_context *movie_ctx);
66
+ const char* qp_get_codec_name(qp_movie_context *movie_ctx, int type);
67
+ int qp_has_audio(qp_movie_context *movie_ctx);
68
+ int qp_has_video(qp_movie_context *movie_ctx);
69
+ int qp_get_num_audio_channels(qp_movie_context *movie_ctx);
70
+ double qp_get_pixel_aspect_ratio(qp_movie_context *movie_ctx);
71
+ int qp_export_movie(qp_movie_context *movie_ctx, const char *filename);
72
+ int qp_get_codec_sample_rate(qp_movie_context *movie_ctx, int type);
73
+ int qp_get_codec_bit_rate(qp_movie_context *movie_ctx, int type);
74
+
75
+
76
+ #define QP_GETFRAME_KEYFRAME -1
77
+ #define QP_GETFRAME_NEXTFRAME 0
78
+ int qp_get_frame(qp_movie_context *movie_ctx, int wanted_frame,
79
+ qp_frame_context **frame_ctx_handle);
80
+
81
+ #endif /* QP_MOVIE_H */
@@ -0,0 +1,27 @@
1
+ #include "qp_util.h"
2
+
3
+ int quadrupel_is_installed() {
4
+ return 0;
5
+ }
6
+
7
+ int quadrupel_init() {
8
+ /* must be called before using avcodec libraries. */
9
+ avcodec_init();
10
+
11
+ /* register all codecs */
12
+ av_register_all();
13
+ return 0;
14
+ }
15
+
16
+ int quadrupel_shutdown() {
17
+ av_free_static();
18
+ return 0;
19
+ }
20
+
21
+ long qp_avcodec_version() {
22
+ return avcodec_version();
23
+ }
24
+
25
+ long qp_avcodec_build() {
26
+ return avcodec_build();
27
+ }
@@ -0,0 +1,18 @@
1
+ #ifndef QUADRUPEL_H
2
+ #define QUADRUPEL_H
3
+
4
+ #include <ffmpeg/avcodec.h>
5
+ #include <ffmpeg/avformat.h>
6
+
7
+ int quadrupel_is_installed();
8
+ int quadrupel_init();
9
+ int quadrupel_shutdown();
10
+
11
+ long qp_avcodec_version();
12
+ long qp_avcodec_build();
13
+
14
+ typedef void *(*qp_malloc_t)(size_t length);
15
+ typedef void (*qp_free_t)(void* ptr);
16
+
17
+
18
+ #endif /* QUADRUPEL_H */
@@ -0,0 +1,60 @@
1
+ #include "quadrupel.h"
2
+ #include "movie.h"
3
+ #include "frame.h"
4
+
5
+ int main(int argc, char **argv)
6
+ {
7
+ char *filename = NULL;
8
+ movie_context *movie_ctx = NULL;
9
+ frame_context *frame_ctx = NULL;
10
+ int i = 0;
11
+ int err = 0;
12
+
13
+ if (argc != 2) {
14
+ return -1;
15
+ }
16
+
17
+ filename = argv[1];
18
+
19
+ // must be called before using any other quadrupel functions
20
+ quadrupel_init();
21
+
22
+ movie_ctx = alloc_movie_ctx();
23
+
24
+ err = open_movie_file(movie_ctx, filename);
25
+
26
+ if (err) {
27
+ printf("Error opening file '%s' Errno: %d\n", filename, err);
28
+ return err;
29
+ }
30
+
31
+ if (has_video(movie_ctx)) {
32
+ char *frame_string;
33
+
34
+ for (i = 1; i <= 8; i++) {
35
+ printf("Frame: %d\n", i);
36
+
37
+ frame_ctx = get_frame(movie_ctx, i);
38
+ if (frame_ctx == NULL) {
39
+ printf("oops!\n");
40
+ exit(-1);
41
+ }
42
+
43
+ output_as_string(frame_ctx, &frame_string);
44
+
45
+ printf("dimensions w:%d h:%d\n", get_frame_width(frame_ctx),
46
+ get_frame_height(frame_ctx));
47
+ crop_frame(frame_ctx, 4, 4, 4, 4);
48
+
49
+ free(frame_string);
50
+
51
+ free_frame_ctx(frame_ctx);
52
+ }
53
+
54
+ }
55
+
56
+ //export(movie_ctx, "out.flv");
57
+ free_movie_ctx(movie_ctx);
58
+
59
+ return 0;
60
+ }
@@ -0,0 +1,236 @@
1
+ #include <ruby.h>
2
+
3
+ #include "qp_frame.h"
4
+ #include "rmovie_frame.h"
5
+
6
+ void mark_frame_ctx(qp_frame_context *frame) {}
7
+
8
+ static void rm_free_frame_ctx(qp_frame_context *frame) {
9
+ qp_free_frame_ctx(frame, NULL);
10
+ }
11
+
12
+
13
+ VALUE wrap_frame_ctx(VALUE klass, qp_frame_context *frame)
14
+ {
15
+ return Data_Wrap_Struct (klass, mark_frame_ctx,
16
+ rm_free_frame_ctx, frame);
17
+ }
18
+
19
+
20
+ VALUE frame_allocate(VALUE klass)
21
+ {
22
+ qp_frame_context* frame = qp_alloc_frame_ctx(NULL);
23
+ return wrap_frame_ctx(klass, frame);
24
+ }
25
+
26
+
27
+ VALUE Frame_get_presentation_timestamp(VALUE self)
28
+ {
29
+ qp_frame_context *frame_ctx = NULL;
30
+
31
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
32
+
33
+ return rb_float_new((double)qp_get_pts(frame_ctx));
34
+ }
35
+
36
+
37
+ VALUE Frame_is_key_frame(VALUE self)
38
+ {
39
+ qp_frame_context *frame_ctx = NULL;
40
+
41
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
42
+
43
+ return qp_frame_is_keyframe(frame_ctx) ? Qtrue : Qfalse;
44
+ }
45
+
46
+
47
+ VALUE Frame_get_width(VALUE self)
48
+ {
49
+ qp_frame_context *frame_ctx = NULL;
50
+
51
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
52
+
53
+ return rb_int_new(qp_get_frame_width(frame_ctx));
54
+ }
55
+
56
+
57
+ VALUE Frame_get_height(VALUE self)
58
+ {
59
+ qp_frame_context *frame_ctx = NULL;
60
+
61
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
62
+
63
+ return rb_int_new(qp_get_frame_height(frame_ctx));
64
+ }
65
+
66
+
67
+ VALUE Frame_crop(int argc, VALUE *argv, VALUE self)
68
+ {
69
+ qp_frame_context *frame_ctx = NULL;
70
+ int crop_top = 0, crop_bottom = 0, crop_left = 0, crop_right = 0;
71
+
72
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
73
+
74
+ switch (argc) {
75
+ case 4:
76
+ if (argv[3] != Qnil) {
77
+
78
+ crop_right = argv[3];
79
+
80
+ /* crop right must be even number for quadrupel cropping */
81
+ if (crop_right % 2) {
82
+ rb_raise(rb_eArgError, "crop right value must be even number.");
83
+ }
84
+ }
85
+ /* fallthru */
86
+ case 3:
87
+ if (argv[2] != Qnil) {
88
+ crop_left = argv[2];
89
+
90
+ /* crop left must be even number for quadrupel cropping */
91
+ if (crop_left % 2) {
92
+ rb_raise(rb_eArgError, "crop left valus must be even number.");
93
+ }
94
+ }
95
+
96
+ /* fallthru */
97
+ case 2:
98
+ if (argv[1] != Qnil) {
99
+ crop_bottom = argv[1];
100
+
101
+ /* crop bottom must be even number for quadrupel cropping */
102
+ if (crop_bottom % 2) {
103
+ rb_raise(rb_eArgError, "crop bottom values must be even number.");
104
+ }
105
+ }
106
+
107
+ /* fallthru */
108
+ case 1:
109
+ if (argv[0] != Qnil) {
110
+ crop_top = argv[0];
111
+
112
+ /* crop top must be even number for quadrupel cropping */
113
+ if (crop_top % 2) {
114
+ rb_raise(rb_eArgError, "crop top value must be even number.");
115
+ }
116
+ }
117
+ break;
118
+ default:
119
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 1 to 4)", argc);
120
+ break;;
121
+ }
122
+
123
+ /* crop frame */
124
+ qp_crop_frame(frame_ctx, crop_top, crop_bottom, crop_left, crop_right);
125
+
126
+ return Qtrue;
127
+ }
128
+
129
+
130
+ VALUE Frame_resize(int argc, VALUE *argv, VALUE self)
131
+ {
132
+ qp_frame_context *frame_ctx = NULL;
133
+ int wanted_width = 0, wanted_height = 0;
134
+ int crop_top = 0, crop_bottom = 0, crop_left = 0, crop_right = 0;
135
+
136
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
137
+
138
+ switch (argc) {
139
+ case 6:
140
+ if (argv[5] != Qnil) {
141
+ crop_right = argv[5];
142
+
143
+ /* crop right must be even number for quadrupel cropping */
144
+ if (crop_right % 2) {
145
+ rb_raise(rb_eArgError, "crop right value must be an even number");
146
+ }
147
+ }
148
+
149
+ /* fallthru */
150
+ case 5:
151
+ if (argv[4] != Qnil) {
152
+ crop_left = argv[4];
153
+
154
+ /* crop left must be even number for quadrupel cropping */
155
+ if (crop_left % 2) {
156
+ rb_raise(rb_eArgError, "crop left value must be an even number");
157
+ }
158
+ }
159
+
160
+ /* fallthru */
161
+ case 4:
162
+ if (argv[3] != Qnil) {
163
+ crop_bottom = argv[3];
164
+
165
+ /* crop bottom must be even number for quadrupel cropping */
166
+ if (crop_bottom % 2) {
167
+ rb_raise(rb_eArgError, "crop top value must be an even number");
168
+ }
169
+ }
170
+
171
+ /* fallthru */
172
+ case 3:
173
+ if (argv[2] != Qnil) {
174
+ crop_top = argv[2];
175
+
176
+ /* crop top must be even number for quadrupel cropping */
177
+ if (crop_top % 2) {
178
+ rb_raise(rb_eArgError, "crop values must be even numbers");
179
+ }
180
+ }
181
+
182
+ /* fallthru */
183
+ case 2:
184
+ if (argv[1] != Qnil) {
185
+ wanted_height = argv[1];
186
+
187
+ /* bounds check wanted height */
188
+ if (wanted_height < 1) {
189
+ rb_raise(rb_eArgError, "frame height must be greater than zero");
190
+ }
191
+
192
+ /* wanted height must be even number for quadrupel resample */
193
+ if (wanted_height % 2) {
194
+ rb_raise(rb_eArgError, "frame height must be an even number.");
195
+ }
196
+ }
197
+ case 1:
198
+ if (argv[0] != Qnil) {
199
+ /* width arg */
200
+ wanted_width = argv[0];
201
+
202
+ /* bounds check wanted width */
203
+ if (wanted_width < 1) {
204
+ rb_raise(rb_eArgError, "frame width must be greater than zero");
205
+ }
206
+
207
+ /* wanted width must be even number for quadrupel resample */
208
+ if (wanted_width % 2) {
209
+ rb_raise(rb_eArgError, "frame width must be an even number.");
210
+ }
211
+ }
212
+ break;
213
+ default:
214
+ rb_raise(rb_eArgError, "wrong number of arguments (%d for 2 to 6)", argc);
215
+ break;
216
+ }
217
+
218
+ /* resize frame */
219
+ qp_resample_frame(frame_ctx, wanted_width, wanted_height,
220
+ crop_top, crop_bottom, crop_left, crop_right);
221
+
222
+ return Qtrue;
223
+ }
224
+
225
+
226
+ VALUE Frame_to_string(VALUE self) {
227
+ qp_frame_context *frame_ctx = NULL;
228
+ unsigned char *frame_as_string = NULL;
229
+ int frame_size = 0;
230
+
231
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
232
+
233
+ frame_size = qp_output_frame_as_string(frame_ctx, &frame_as_string);
234
+
235
+ return rb_tainted_str_new(frame_as_string, frame_size);
236
+ }
@@ -0,0 +1,10 @@
1
+
2
+ // Methods
3
+ VALUE frame_allocate(VALUE klass);
4
+ VALUE Frame_get_width(VALUE);
5
+ VALUE Frame_get_height(VALUE);
6
+ VALUE Frame_resize(int argc, VALUE *argv, VALUE self);
7
+ VALUE Frame_crop(int argc, VALUE *argv, VALUE self);
8
+ VALUE Frame_is_key_frame(VALUE);
9
+ VALUE Frame_get_presentation_timestamp(VALUE);
10
+ VALUE Frame_to_string(VALUE);
@@ -0,0 +1,100 @@
1
+ #include <ruby.h>
2
+
3
+ #include "qp_util.h"
4
+
5
+ #include "rmovie_movie.h"
6
+ #include "rmovie_frame.h"
7
+
8
+ #define RMOVIE_VERSION "0.5"
9
+
10
+ /* Module */
11
+ static VALUE rb_mRMovie;
12
+
13
+ VALUE rb_cMovie;
14
+ VALUE rb_cFrame;
15
+
16
+ static void version_constants(void)
17
+ {
18
+ const char *rmovie_version;
19
+ volatile VALUE str;
20
+ char long_version[1000];
21
+
22
+ rmovie_version = RMOVIE_VERSION;
23
+
24
+ str = rb_str_new2(rmovie_version);
25
+ rb_obj_freeze(str);
26
+ rb_define_const(rb_mRMovie, "Version", str);
27
+
28
+ sprintf(long_version,
29
+ "This is rmovie %s. Copyright (C) 2006 by Todd Kirby\n"
30
+ "Web page: http://rmovie.rubyforge.org\n"
31
+ "Email: ffmpeg.php@gmail.com\n",
32
+ rmovie_version);
33
+
34
+ str = rb_str_new2(long_version);
35
+ rb_obj_freeze(str);
36
+ rb_define_const(rb_mRMovie, "Long_version", str);
37
+
38
+ }
39
+
40
+
41
+ void Init_rmovie()
42
+ {
43
+ rb_mRMovie = rb_define_module("RMovie");
44
+
45
+ /* Must be called before using any quadrupal functions */
46
+ quadrupel_init();
47
+
48
+ /* Movie */
49
+ rb_cMovie = rb_define_class_under(rb_mRMovie, "Movie", rb_cObject);
50
+ rb_define_alloc_func(rb_cMovie, movie_allocate);
51
+ rb_define_method(rb_cMovie, "initialize", movie_initialize, 1);
52
+ rb_define_method(rb_cMovie, "duration", Movie_get_duration, 0);
53
+ rb_define_method(rb_cMovie, "frame_count", Movie_get_frame_count, 0);
54
+ rb_define_method(rb_cMovie, "frame_rate", Movie_get_frame_rate, 0);
55
+ rb_define_method(rb_cMovie, "file_name", Movie_get_file_name, 0);
56
+ rb_define_method(rb_cMovie, "comment", Movie_get_comment, 0);
57
+ rb_define_method(rb_cMovie, "title", Movie_get_title, 0);
58
+ rb_define_method(rb_cMovie, "author", Movie_get_author, 0);
59
+ rb_define_alias(rb_cMovie, "artist", "author");
60
+ rb_define_method(rb_cMovie, "copyright", Movie_get_copyright, 0);
61
+ rb_define_method(rb_cMovie, "album", Movie_get_album, 0);
62
+ rb_define_method(rb_cMovie, "genre", Movie_get_genre, 0);
63
+ rb_define_method(rb_cMovie, "year", Movie_get_year, 0);
64
+ rb_define_method(rb_cMovie, "track", Movie_get_track, 0);
65
+ rb_define_method(rb_cMovie, "frame_width", Movie_get_frame_width, 0);
66
+ rb_define_method(rb_cMovie, "frame_height", Movie_get_frame_height, 0);
67
+ rb_define_method(rb_cMovie, "frame_number",
68
+ Movie_get_frame_number, 0);
69
+ rb_define_method(rb_cMovie, "pixel_format", Movie_get_pixel_format, 0);
70
+ rb_define_method(rb_cMovie, "bit_rate", Movie_get_bit_rate, 0);
71
+ rb_define_method(rb_cMovie, "has_audio?", Movie_has_audio, 0);
72
+ rb_define_method(rb_cMovie, "video_codec", Movie_get_video_codec, 0);
73
+ rb_define_method(rb_cMovie, "audio_codec", Movie_get_audio_codec, 0);
74
+ rb_define_method(rb_cMovie, "audio_channels",
75
+ Movie_get_num_audio_channels, 0);
76
+ rb_define_method(rb_cMovie, "pixel_aspect_ratio",
77
+ Movie_get_pixel_aspect_ratio, 0);
78
+ rb_define_alias(rb_cMovie, "aspect_ratio", "pixel_aspect_ratio");
79
+ rb_define_method(rb_cMovie, "frame", Movie_get_frame, -1);
80
+ rb_define_method(rb_cMovie, "next_key_frame", Movie_get_next_key_frame, 0);
81
+ rb_define_method(rb_cMovie, "export", Movie_export, 1);
82
+
83
+ /* Frame */
84
+ rb_cFrame = rb_define_class_under (rb_mRMovie, "Frame", rb_cObject);
85
+ rb_define_alloc_func(rb_cFrame, frame_allocate);
86
+ rb_define_method(rb_cFrame, "width", Frame_get_width, 0);
87
+ rb_define_method(rb_cFrame, "height", Frame_get_height, 0);
88
+ rb_define_method(rb_cFrame, "resize!", Frame_resize, 2);
89
+ rb_define_method(rb_cFrame, "crop!", Frame_crop, 4);
90
+ rb_define_method(rb_cFrame, "key_frame?", Frame_is_key_frame, 0);
91
+ rb_define_method(rb_cFrame, "presentation_timestamp",
92
+ Frame_get_presentation_timestamp, 0);
93
+ rb_define_alias(rb_cFrame, "pts", "presentation_timestamp");
94
+ rb_define_method(rb_cFrame, "to_s", Frame_to_string, 0);
95
+ rb_define_alias(rb_cFrame, "to_string", "to_s");
96
+
97
+ version_constants();
98
+ }
99
+
100
+