21 #include <grass/gis.h>
22 #include <grass/glocale.h>
23 #include <grass/ogsf_proto.h>
24 #include <grass/gstypes.h>
30 #if LIBAVUTIL_VERSION_MAJOR < 51
34 #include <mathematics.h>
38 #define STREAM_DURATION 5.0
39 #define STREAM_FRAME_RATE 25
40 #define STREAM_NB_FRAMES ((int)(STREAM_DURATION * STREAM_FRAME_RATE))
41 #define STREAM_PIX_FMT PIX_FMT_YUV420P
43 AVFrame *picture, *tmp_picture;
44 uint8_t *video_outbuf;
45 int frame_count, video_outbuf_size;
61 static AVStream *add_video_stream(AVFormatContext * oc,
int codec_id,
int w,
67 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 112, 0)
68 st = av_new_stream(oc, 0);
70 st = avformat_new_stream(oc,
NULL);
73 G_warning(_(
"Unable to allocate stream"));
78 c->codec_id = codec_id;
79 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 123, 0)
80 c->codec_type = CODEC_TYPE_VIDEO;
82 c->codec_type = AVMEDIA_TYPE_VIDEO;
94 c->time_base.den = STREAM_FRAME_RATE;
97 c->pix_fmt = STREAM_PIX_FMT;
98 if (c->codec_id == CODEC_ID_MPEG2VIDEO) {
102 if (c->codec_id == CODEC_ID_MPEG1VIDEO) {
109 if (!strcmp(oc->oformat->name,
"mp4") || !strcmp(oc->oformat->name,
"mov")
110 || !strcmp(oc->oformat->name,
"3gp"))
111 c->flags |= CODEC_FLAG_GLOBAL_HEADER;
113 c->flags |= CODEC_FLAG_QSCALE;
116 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
117 c->global_quality = st->quality = FF_QP2LAMBDA * 10;
119 c->global_quality = FF_QP2LAMBDA * 10;
135 static AVFrame *alloc_picture(
int pix_fmt,
int width,
int height)
138 uint8_t *picture_buf;
141 picture = avcodec_alloc_frame();
146 size = avpicture_get_size(pix_fmt, width, height);
147 picture_buf = av_malloc(size);
154 avpicture_fill((AVPicture *) picture, picture_buf,
155 pix_fmt, width, height);
166 static void open_video(AVFormatContext * oc, AVStream * st)
174 codec = avcodec_find_encoder(c->codec_id);
181 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
182 if (avcodec_open(c, codec) < 0) {
184 if (avcodec_open2(c, codec,
NULL) < 0) {
191 if (!(oc->oformat->flags & AVFMT_RAWPICTURE)) {
198 video_outbuf_size = 200000;
199 video_outbuf = av_malloc(video_outbuf_size);
203 picture = alloc_picture(c->pix_fmt, c->width, c->height);
205 G_warning(_(
"Unable to allocate picture"));
213 if (c->pix_fmt != PIX_FMT_YUV420P) {
214 tmp_picture = alloc_picture(PIX_FMT_YUV420P, c->width, c->height);
216 G_warning(_(
"Unable to allocate temporary picture"));
228 static void write_video_frame(AVFormatContext * oc, AVStream * st)
235 if (oc->oformat->flags & AVFMT_RAWPICTURE) {
240 av_init_packet(&pkt);
241 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
242 pkt.flags |= PKT_FLAG_KEY;
244 pkt.flags |= AV_PKT_FLAG_KEY;
246 pkt.stream_index = st->index;
247 pkt.data = (uint8_t *) picture;
248 pkt.size =
sizeof(AVPicture);
250 ret = av_write_frame(oc, &pkt);
255 avcodec_encode_video(c, video_outbuf, video_outbuf_size, picture);
260 av_init_packet(&pkt);
263 av_rescale_q(c->coded_frame->pts, c->time_base,
265 if (c->coded_frame->key_frame)
266 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
267 pkt.flags |= PKT_FLAG_KEY;
269 pkt.flags |= AV_PKT_FLAG_KEY;
271 pkt.stream_index = st->index;
272 pkt.data = video_outbuf;
276 ret = av_write_frame(oc, &pkt);
283 G_warning(_(
"Error while writing video frame"));
295 static void close_video(AVStream * st)
297 avcodec_close(st->codec);
298 av_free(picture->data[0]);
301 av_free(tmp_picture->data[0]);
302 av_free(tmp_picture);
304 av_free(video_outbuf);
323 glGetIntegerv(GL_VIEWPORT, tmp);
325 r = tmp[0] + tmp[2] - 1;
327 t = tmp[1] + tmp[3] - 1;
335 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
336 fmt = guess_format(
NULL, filename,
NULL);
338 fmt = av_guess_format(
NULL, filename,
NULL);
341 G_warning(_(
"Unable to deduce output format from file extension: using MPEG"));
342 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 32, 0)
343 fmt = guess_format(
"mpeg",
NULL,
NULL);
345 fmt = av_guess_format(
"mpeg",
NULL,
NULL);
349 G_warning(_(
"Unable to find suitable output format"));
354 oc = avformat_alloc_context();
360 snprintf(oc->filename,
sizeof(oc->filename),
"%s", filename);
365 fmt->video_codec = CODEC_ID_XVID;
369 if (fmt->video_codec != CODEC_ID_NONE) {
371 add_video_stream(oc, fmt->video_codec, (r - l + 1), (t - b + 1));
375 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
376 if (av_set_parameters(oc,
NULL) < 0) {
378 if (avformat_write_header(oc,
NULL) < 0) {
380 G_warning(_(
"Invalid output format parameters"));
384 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
385 dump_format(oc, 0, filename, 1);
387 av_dump_format(oc, 0, filename, 1);
393 open_video(oc, video_st);
396 if (!(fmt->flags & AVFMT_NOFILE)) {
397 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 112, 0)
398 if (url_fopen(&oc->pb, filename, URL_WRONLY) < 0) {
400 if (avio_open(&oc->pb, filename, AVIO_FLAG_WRITE) < 0) {
402 G_warning(_(
"Unable to open <%s>"), filename);
408 #if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
411 avformat_write_header(oc,
NULL);
415 G_warning(_(
"OGSF library has not been built with MPEG output support"));
431 unsigned int xsize, ysize, x;
434 unsigned char *pixbuf;
438 for (y = ysize - 1; y >= 0; y--) {
439 for (x = 0; x < xsize; x++) {
440 unsigned char r = pixbuf[(y * xsize + x) * 4 + 0];
441 unsigned char g = pixbuf[(y * xsize + x) * 4 + 1];
442 unsigned char b = pixbuf[(y * xsize + x) * 4 + 2];
444 yy = (0.257 *
r) + (0.504 * g) + (0.098 *
b) + 16;;
445 vv = (0.439 *
r) - (0.368 * g) - (0.071 *
b) + 128;
446 uu = -(0.148 *
r) - (0.291 * g) + (0.439 *
b) + 128;
448 picture->data[0][xy] = yy;
450 if ((x % 2) && (y % 2)) {
451 picture->data[1][xy_uv] = uu;
452 picture->data[2][xy_uv] = vv;
462 write_video_frame(oc, video_st);
480 close_video(video_st);
483 av_write_trailer(oc);
486 for (i = 0; i < oc->nb_streams; i++) {
487 av_freep(&oc->streams[i]->codec);
488 av_freep(&oc->streams[i]);
491 if (!(fmt->flags & AVFMT_NOFILE)) {
493 #if (LIBAVFORMAT_VERSION_INT>>16) < 52
495 #elif LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(52, 100, 0)
506 G_debug(3,
"Closed MPEG stream");
void G_free(void *buf)
Free allocated memory.
int gsd_close_mpeg(void)
Close the mpeg, free buffer, and close file.
void G_verbose_message(const char *msg,...)
Print a message to stderr but only if module is in verbose mode.
int gsd_init_mpeg(const char *filename)
Initialize FAME setup mpeg defaults and open file for writing.
int gsd_write_mpegframe(void)
Get RGB pixbuf and convert to YUV 4:2:0.
G_warning("category support for [%s] in mapset [%s] %s", name, mapset, type)
int G_debug(int level, const char *msg,...)
Print debugging message.
int gsd_getimage(unsigned char **pixbuf, unsigned int *xsize, unsigned int *ysize)
Get image of current GL screen.
tuple h
panel.defaultSize = wx.CheckBox(panel, id = wx.ID_ANY, label = _("Use default size")) panel...