rmovie 0.5.0 → 0.5.1

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.
@@ -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