rmovie 0.5.0 → 0.5.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,36 @@
1
+ #ifndef QP_ANIMATED_GIF_H
2
+ #define QP_ANIMATED_GIF_H
3
+
4
+ #define QP_ANIMATED_GIF_NO_LOOP -1
5
+ #define QP_ANIMATED_GIF_INFINITE_LOOP 0
6
+ #define QP_ANIMATED_GIF_MAX_LOOP_COUNT 65535
7
+
8
+ #define QP_ANIMATED_GIF_STATE_UNOPENED -1
9
+ #define QP_ANIMATED_GIF_STATE_CLOSED 0
10
+ #define QP_ANIMATED_GIF_STATE_OPENED 1
11
+
12
+ typedef struct {
13
+ int state;
14
+ AVStream *video_st;
15
+ AVOutputFormat *fmt;
16
+ AVFormatContext *fmt_ctx;
17
+ AVCodecContext *codec_ctx;
18
+
19
+ uint8_t *video_outbuf;
20
+ int video_outbuf_size;
21
+ } qp_animated_gif_context;
22
+
23
+ qp_animated_gif_context* qp_alloc_animated_gif_ctx(qp_malloc_t malloc_func);
24
+
25
+ void qp_free_animated_gif_ctx(qp_animated_gif_context *qp_animated_gif,
26
+ qp_free_t free_func);
27
+
28
+ int qp_open_animated_gif_file(qp_animated_gif_context *qp_animated_gif,
29
+ char* filename, int width, int height, int frame_rate, int loop_count);
30
+
31
+ int qp_close_animated_gif_ctx(qp_animated_gif_context *qp_animated_gif);
32
+
33
+ int qp_add_animated_gif_frame(qp_animated_gif_context *qp_animated_gif,
34
+ qp_frame_context *frame);
35
+
36
+ #endif // QP_ANIMATED_GIF_H
@@ -8,14 +8,6 @@
8
8
  #define LRINT(x) ((long) ((x)+0.5))
9
9
  #define MAX(a,b) ((a) > (b) ? (a) : (b))
10
10
 
11
- #if LIBAVFORMAT_BUILD > 4628
12
- #define GET_CODEC_FIELD(codec, field) codec->field
13
- #define GET_CODEC_PTR(codec) codec
14
- #else
15
- #define GET_CODEC_FIELD(codec, field) codec.field
16
- #define GET_CODEC_PTR(codec) &codec
17
- #endif
18
-
19
11
  #define MAX_AUDIO_PACKET_SIZE (128 * 1024)
20
12
 
21
13
  /*
@@ -836,11 +828,11 @@ int write_audio_frame(qp_movie_context *movie_ctx, AVFormatContext *oc,
836
828
  AVStream *add_audio_stream(AVCodecContext *icodec,
837
829
  AVFormatContext *oc, int codec_id)
838
830
  {
839
- AVCodecContext *c;
840
- AVStream *st;
831
+ AVCodecContext *c = NULL;
832
+ AVStream *st = NULL;
841
833
 
842
834
  st = av_new_stream(oc, 1);
843
- if (!st) {
835
+ if (st == NULL) {
844
836
  fprintf(stderr, "Could not alloc stream\n");
845
837
  return NULL;
846
838
  }
@@ -861,11 +853,11 @@ AVStream *add_audio_stream(AVCodecContext *icodec,
861
853
  static AVStream *add_video_stream(qp_movie_context *movie_ctx,
862
854
  AVFormatContext *oc, int codec_id)
863
855
  {
864
- AVCodecContext *c;
865
- AVStream *st;
856
+ AVCodecContext *c = NULL;
857
+ AVStream *st = NULL;
866
858
 
867
859
  st = av_new_stream(oc, 0);
868
- if (!st) {
860
+ if (st == NULL) {
869
861
  fprintf(stderr, "Could not alloc stream\n");
870
862
  return NULL;
871
863
  }
@@ -914,16 +906,16 @@ static AVStream *add_video_stream(qp_movie_context *movie_ctx,
914
906
 
915
907
  AVFrame *alloc_picture(int pix_fmt, int width, int height)
916
908
  {
917
- AVFrame *picture;
918
- uint8_t *picture_buf;
919
- int size;
909
+ AVFrame *picture = NULL;
910
+ uint8_t *picture_buf = NULL;
911
+ int size = 0;
920
912
 
921
913
  picture = avcodec_alloc_frame();
922
- if (!picture)
914
+ if (picture == NULL)
923
915
  return NULL;
924
916
  size = avpicture_get_size(pix_fmt, width, height);
925
917
  picture_buf = (uint8_t *)malloc(size);
926
- if (!picture_buf) {
918
+ if (picture_buf == NULL) {
927
919
  av_free(picture);
928
920
  return NULL;
929
921
  }
@@ -937,7 +929,7 @@ static int write_video_frame(qp_movie_context *movie_ctx, AVFormatContext *oc,
937
929
  AVStream *st, AVFrame *decoded_frame, int pixel_format)
938
930
  {
939
931
  int out_size, ret;
940
- AVCodecContext *c;
932
+ AVCodecContext *c = NULL;
941
933
 
942
934
  c = st->codec;
943
935
 
@@ -1164,6 +1156,7 @@ int qp_export_movie(qp_movie_context *movie_ctx, const char *filename)
1164
1156
 
1165
1157
  /* free the streams */
1166
1158
  for (i = 0; i < oc->nb_streams; i++) {
1159
+ av_freep(&oc->streams[i]->codec);
1167
1160
  av_freep(&oc->streams[i]);
1168
1161
  }
1169
1162
 
@@ -4,6 +4,14 @@
4
4
  #include <ffmpeg/avcodec.h>
5
5
  #include <ffmpeg/avformat.h>
6
6
 
7
+ #if LIBAVFORMAT_BUILD > 4628
8
+ #define GET_CODEC_FIELD(codec, field) codec->field
9
+ #define GET_CODEC_PTR(codec) codec
10
+ #else
11
+ #define GET_CODEC_FIELD(codec, field) codec.field
12
+ #define GET_CODEC_PTR(codec) &codec
13
+ #endif
14
+
7
15
  int quadrupel_is_installed();
8
16
  int quadrupel_init();
9
17
  int quadrupel_shutdown();
@@ -14,5 +22,4 @@ long qp_avcodec_build();
14
22
  typedef void *(*qp_malloc_t)(size_t length);
15
23
  typedef void (*qp_free_t)(void* ptr);
16
24
 
17
-
18
25
  #endif /* QUADRUPEL_H */
@@ -4,14 +4,17 @@
4
4
 
5
5
  #include "rmovie_movie.h"
6
6
  #include "rmovie_frame.h"
7
+ #include "rmovie_animated_gif.h"
7
8
 
8
- #define RMOVIE_VERSION "0.5"
9
+ #define RMOVIE_VERSION "0.5.1"
9
10
 
10
11
  /* Module */
11
12
  static VALUE rb_mRMovie;
12
13
 
14
+ /* Classes */
13
15
  VALUE rb_cMovie;
14
16
  VALUE rb_cFrame;
17
+ VALUE rb_cAnimated_GIF;
15
18
 
16
19
  static void version_constants(void)
17
20
  {
@@ -94,6 +97,13 @@ void Init_rmovie()
94
97
  rb_define_method(rb_cFrame, "to_s", Frame_to_string, 0);
95
98
  rb_define_alias(rb_cFrame, "to_string", "to_s");
96
99
 
100
+ /* Animated GIF */
101
+ rb_cAnimated_GIF = rb_define_class_under(rb_mRMovie, "Animated_GIF", rb_cObject);
102
+ rb_define_alloc_func(rb_cAnimated_GIF, animated_gif_allocate);
103
+ rb_define_method(rb_cAnimated_GIF, "initialize", animated_gif_initialize, -1);
104
+ rb_define_method(rb_cAnimated_GIF, "add_frame", Animated_gif_add_frame, 1);
105
+ rb_define_method(rb_cAnimated_GIF, "close", Animated_gif_close, 0);
106
+
97
107
  version_constants();
98
108
  }
99
109
 
@@ -0,0 +1,7 @@
1
+ #ifndef RMOVIE_H
2
+ #define RMOVIE_H
3
+
4
+ #define ERR_IF_LESS_THAN(n, x, label) if ((x) < (n)) rb_raise(rb_eArgError, "%s must be greater than %d", label, n)
5
+ #define ERR_IF_ODD(x, label) if ((x) % 2) rb_raise(rb_eArgError, "%s must be an even number", label)
6
+
7
+ #endif // RMOVIE_H
@@ -0,0 +1,101 @@
1
+ #include <ruby.h>
2
+
3
+ #include "qp_frame.h"
4
+ #include "qp_animated_gif.h"
5
+
6
+ #include "rmovie.h"
7
+ #include "rmovie_animated_gif.h"
8
+ #include "rmovie_frame.h"
9
+
10
+
11
+ void mark_animated_gif_ctx(qp_animated_gif_context *animated_gif)
12
+ {
13
+ }
14
+
15
+
16
+ static void rm_free_animated_gif_ctx(qp_animated_gif_context *animated_gif_ctx)
17
+ {
18
+ qp_close_animated_gif_ctx(animated_gif_ctx);
19
+ qp_free_animated_gif_ctx(animated_gif_ctx, NULL);
20
+ }
21
+
22
+
23
+ VALUE wrap_animated_gif_ctx(VALUE klass, qp_animated_gif_context *animated_gif_ctx)
24
+ {
25
+ return Data_Wrap_Struct (klass, mark_animated_gif_ctx,
26
+ rm_free_animated_gif_ctx, animated_gif_ctx);
27
+ }
28
+
29
+
30
+ VALUE animated_gif_allocate(VALUE klass)
31
+ {
32
+ qp_animated_gif_context* animated_gif = qp_alloc_animated_gif_ctx(NULL);
33
+ return wrap_animated_gif_ctx(klass, animated_gif);
34
+ }
35
+
36
+
37
+ VALUE animated_gif_initialize(int argc, VALUE *argv, VALUE self)
38
+ {
39
+ qp_animated_gif_context *animated_gif_ctx;
40
+ int width, height, frame_rate, loop_count;
41
+ VALUE vfilename, vwidth, vheight, vframe_rate, vloop_count;
42
+ char* filename;
43
+
44
+ rb_scan_args(argc, argv, "41", &vfilename, &vwidth, &vheight, &vframe_rate, &vloop_count);
45
+
46
+ Check_Type(vfilename, T_STRING);
47
+ Check_Type(vwidth, T_FIXNUM);
48
+ Check_Type(vheight, T_FIXNUM);
49
+ Check_Type(vframe_rate, T_FIXNUM);
50
+
51
+
52
+ if (RTEST(vloop_count)) {
53
+ Check_Type(vloop_count, T_FIXNUM);
54
+ loop_count = NUM2INT(vloop_count);
55
+ } else {
56
+ loop_count = QP_ANIMATED_GIF_NO_LOOP;
57
+ }
58
+
59
+ width = NUM2UINT(vwidth);
60
+ height = NUM2UINT(vheight);
61
+ frame_rate = NUM2UINT(vframe_rate);
62
+
63
+ ERR_IF_LESS_THAN(1, width, "width");
64
+ ERR_IF_ODD(width, "width");
65
+ ERR_IF_LESS_THAN(1, height, "height");
66
+ ERR_IF_ODD(height, "height");
67
+ ERR_IF_LESS_THAN(1, frame_rate, "frame rate");
68
+
69
+ Data_Get_Struct(self, qp_animated_gif_context, animated_gif_ctx);
70
+
71
+ SafeStringValue(vfilename);
72
+ if (qp_open_animated_gif_file(animated_gif_ctx, StringValueCStr(vfilename),
73
+ width, height, frame_rate, loop_count)) {
74
+ rb_sys_fail(filename);
75
+ }
76
+
77
+ return self;
78
+ }
79
+
80
+
81
+ VALUE Animated_gif_add_frame(VALUE self, VALUE frame)
82
+ {
83
+ qp_animated_gif_context *animated_gif_ctx;
84
+ qp_frame_context *frame_ctx;
85
+
86
+ Data_Get_Struct(self, qp_animated_gif_context, animated_gif_ctx);
87
+
88
+ Data_Get_Struct(frame, qp_frame_context, frame_ctx);
89
+
90
+ qp_add_animated_gif_frame(animated_gif_ctx, frame_ctx);
91
+ }
92
+
93
+
94
+ VALUE Animated_gif_close(VALUE self)
95
+ {
96
+ qp_animated_gif_context *animated_gif_ctx;
97
+
98
+ Data_Get_Struct(self, qp_animated_gif_context, animated_gif_ctx);
99
+
100
+ qp_close_animated_gif_ctx(animated_gif_ctx);
101
+ }
@@ -0,0 +1,6 @@
1
+
2
+ // Methods
3
+ VALUE animated_gif_allocate(VALUE klass);
4
+ VALUE animated_gif_initialize(int argc, VALUE *argv, VALUE self);
5
+ VALUE Animated_gif_add_frame(VALUE self, VALUE frame);
6
+ VALUE Animated_gif_close(VALUE self);
@@ -1,9 +1,12 @@
1
1
  #include <ruby.h>
2
2
 
3
3
  #include "qp_frame.h"
4
+ #include "rmovie.h"
4
5
  #include "rmovie_frame.h"
5
6
 
6
- void mark_frame_ctx(qp_frame_context *frame) {}
7
+ void mark_frame_ctx(qp_frame_context *frame)
8
+ {
9
+ }
7
10
 
8
11
  static void rm_free_frame_ctx(qp_frame_context *frame) {
9
12
  qp_free_frame_ctx(frame, NULL);
@@ -63,161 +66,82 @@ VALUE Frame_get_height(VALUE self)
63
66
  return rb_int_new(qp_get_frame_height(frame_ctx));
64
67
  }
65
68
 
66
-
67
- VALUE Frame_crop(int argc, VALUE *argv, VALUE self)
69
+ VALUE Frame_crop(VALUE self, VALUE crop_top, VALUE crop_bottom,
70
+ VALUE crop_left, VALUE crop_right)
68
71
  {
69
72
  qp_frame_context *frame_ctx = NULL;
70
- int crop_top = 0, crop_bottom = 0, crop_left = 0, crop_right = 0;
73
+ int top = 0, bottom = 0, left = 0, right = 0;
74
+
75
+ Data_Get_Struct(self, qp_frame_context, frame_ctx);
76
+
77
+ Check_Type(crop_top, T_FIXNUM);
78
+ Check_Type(crop_bottom, T_FIXNUM);
79
+ Check_Type(crop_left, T_FIXNUM);
80
+ Check_Type(crop_right, T_FIXNUM);
81
+
82
+ top = FIX2UINT(crop_top);
83
+ bottom = FIX2UINT(crop_bottom);
84
+ left = FIX2UINT(crop_left);
85
+ right = FIX2UINT(crop_right);
71
86
 
72
87
  Data_Get_Struct(self, qp_frame_context, frame_ctx);
73
88
 
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
- }
89
+ ERR_IF_LESS_THAN(1, top, "crop top");
90
+ ERR_IF_ODD(top, "crop top");
91
+ ERR_IF_LESS_THAN(1, bottom, "crop bottom");
92
+ ERR_IF_ODD(bottom, "crop bottom");
93
+ ERR_IF_LESS_THAN(1, right, "crop right");
94
+ ERR_IF_ODD(right, "crop right");
95
+ ERR_IF_LESS_THAN(1, left, "crop left");
96
+ ERR_IF_ODD(left, "crop left");
122
97
 
123
98
  /* crop frame */
124
- qp_crop_frame(frame_ctx, crop_top, crop_bottom, crop_left, crop_right);
99
+ qp_crop_frame(frame_ctx, right, right, left, right);
125
100
 
126
101
  return Qtrue;
127
102
  }
128
103
 
129
104
 
130
- VALUE Frame_resize(int argc, VALUE *argv, VALUE self)
105
+ VALUE Frame_resize(VALUE self, VALUE wanted_width, VALUE wanted_height)
131
106
  {
132
107
  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;
108
+ int width = 0, height = 0;
135
109
 
110
+ Check_Type(wanted_width, T_FIXNUM);
111
+ Check_Type(wanted_height, T_FIXNUM);
112
+
113
+ width = FIX2UINT(wanted_width);
114
+ height = FIX2UINT(wanted_height);
115
+
136
116
  Data_Get_Struct(self, qp_frame_context, frame_ctx);
137
117
 
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
- }
118
+ ERR_IF_LESS_THAN(1, height, "height");
119
+ ERR_IF_ODD(height, "height");
120
+ ERR_IF_LESS_THAN(1, width, "width");
121
+ ERR_IF_ODD(width, "width");
122
+
123
+ /* bounds check wanted height */
124
+ if (height < 1) {
125
+ rb_raise(rb_eArgError, "frame height must be greater than zero");
126
+ }
127
+
128
+ /* wanted height must be even number for quadrupel resample */
129
+ if (height % 2) {
130
+ rb_raise(rb_eArgError, "frame height must be an even number.");
131
+ }
132
+
133
+ /* bounds check wanted width */
134
+ if (width < 1) {
135
+ rb_raise(rb_eArgError, "frame width must be greater than zero");
136
+ }
137
+
138
+ /* wanted width must be even number for quadrupel resample */
139
+ if (width % 2) {
140
+ rb_raise(rb_eArgError, "frame width must be an even number.");
141
+ }
217
142
 
218
143
  /* resize frame */
219
- qp_resample_frame(frame_ctx, wanted_width, wanted_height,
220
- crop_top, crop_bottom, crop_left, crop_right);
144
+ qp_resample_frame(frame_ctx, width, height, 0, 0, 0, 0);
221
145
 
222
146
  return Qtrue;
223
147
  }
@@ -226,7 +150,7 @@ VALUE Frame_resize(int argc, VALUE *argv, VALUE self)
226
150
  VALUE Frame_to_string(VALUE self) {
227
151
  qp_frame_context *frame_ctx = NULL;
228
152
  unsigned char *frame_as_string = NULL;
229
- int frame_size = 0;
153
+ unsigned int frame_size = 0;
230
154
 
231
155
  Data_Get_Struct(self, qp_frame_context, frame_ctx);
232
156