Hi everyone

I've had some video processing tasks and noticed the octave video-1.0.2 package from OctaveForge has fallen into disrepair. I've emailed the designated maintainer Xavier Delacour some days ago but haven't received a reply yet, so I hope this is the right place to hand in the patch set.

Most of the work to make it play nice with newer ffmpeg versions has been done by Nitzan [1], my fixes make it correctly return NumFrames and the file size with newer ffmpeg versions, plus not reject videos with odd dimension sizes.

Please cc me as I'm not subscribed to the dev list.

cheers
Donjan Rodic

[1] http://sourceforge.net/mailarchive/forum.php?thread_name=1347827972483-4644202.post%40n4.nabble.com&forum_name=octave-dev
diff -ur video-1.0.2/DESCRIPTION video-new/DESCRIPTION
--- video-1.0.2/DESCRIPTION	2009-05-08 15:17:36.000000000 +0200
+++ video-new/DESCRIPTION	2012-10-05 12:45:30.508748789 +0200
@@ -7,6 +7,6 @@
 Description: Implements addframe, avifile, aviinfo, and aviread, using ffmpeg. (and approximately conforms to Matlab interface)
 Depends: octave (>= 2.9.12)
 Autoload: yes
-SystemRequirements: ffmpeg
+SystemRequirements: >=ffmpeg-0.7
 License: BSD
 Url: http://octave.sf.net
diff -ur video-1.0.2/src/AVHandler.cc video-new/src/AVHandler.cc
--- video-1.0.2/src/AVHandler.cc	2009-05-08 15:17:36.000000000 +0200
+++ video-new/src/AVHandler.cc	2012-10-05 12:56:31.148734048 +0200
@@ -64,7 +64,7 @@
 	if (av_output->pb->buf_ptr) {
 	    while (write_frame() > 0) {}
 	    av_write_trailer(av_output);
-	    if (url_fclose( av_output->pb ) < 0)
+	    if (avio_close( av_output->pb ) < 0)
 		(*out) << "AVHandler: cannot close output file" << std::endl;
 	}
 	av_free(av_output);
@@ -78,7 +78,7 @@
     }
 
     if (av_input) {
-	av_close_input_file(av_input);
+	avformat_close_input(&av_input);
     } else {
 	// close output stream
 	if (vstream) av_freep(&vstream);    
@@ -94,8 +94,8 @@
 AVHandler::setup_write() {
     av_register_all();
 
-    AVOutputFormat *avifmt;   
-    for (avifmt = first_oformat; avifmt != NULL; avifmt = avifmt->next) {
+    AVOutputFormat *avifmt = NULL;   
+    while (NULL != (avifmt = av_oformat_next(avifmt))) {
 	if (std::string(avifmt->name) == "avi") {
 	    break;
 	}
@@ -106,7 +106,7 @@
 	return -1;
     }
     
-    av_output = av_alloc_format_context();
+    av_output = avformat_alloc_context();
     if (!av_output) {
 	(*out) << "AVHandler: Memory error allocating format context" << std::endl;
 	return -1;
@@ -121,17 +121,18 @@
     }
     
     /* av_set_parameters is mandatory */
+    // FIXME: it's deprecated, but there's no replacement yet
     if (av_set_parameters(av_output, NULL) < 0) {
 	(*out) << "AVHandler: Error setting output format parameters" << std::endl;
 	return -1;
     }
 
-    snprintf(av_output->filename, sizeof(av_output->filename), "%s", filename.c_str());
-    snprintf(av_output->title, sizeof(av_output->title), "%s", title.c_str());
-    snprintf(av_output->author, sizeof(av_output->author), "%s", author.c_str());
-    snprintf(av_output->comment, sizeof(av_output->comment), "%s", comment.c_str());
+    // FIXME: snprintf(av_output->filename, sizeof(av_output->filename), "%s", filename.c_str());
+    // FIXME: snprintf(av_output->title, sizeof(av_output->title), "%s", title.c_str());
+    // FIXME: snprintf(av_output->author, sizeof(av_output->author), "%s", author.c_str());
+    // FIXME: snprintf(av_output->comment, sizeof(av_output->comment), "%s", comment.c_str());
     
-    if (url_fopen(&av_output->pb, filename.c_str(), URL_WRONLY) < 0) {
+    if (avio_open(&av_output->pb, filename.c_str(), URL_WRONLY) < 0) {
 	(*out) << "AVHandler: Could not open \"" << filename << "\" for output" << std::endl;
 	return -1;
     }
@@ -141,8 +142,8 @@
     frame = create_frame(vstream->codec->pix_fmt);
     rgbframe = create_frame(PIX_FMT_RGB24);
     if (!frame || !rgbframe) return -1;
-    
-    av_write_header(av_output);
+
+    avformat_write_header(av_output, NULL);
     
     return 0;
 }
@@ -151,18 +152,18 @@
 AVHandler::setup_read() {
     av_register_all();
 
-    if (av_open_input_file(&av_input, filename.c_str(), NULL, 0, NULL) != 0) {
+    if (avformat_open_input(&av_input, filename.c_str(), NULL, NULL) != 0) {
 	(*out) << "AVHandler: Could not open \"" << filename << "\" for reading" << std::endl;
 	return -1;
     }
 
-    if (av_find_stream_info(av_input) < 0) {
+    if (avformat_find_stream_info(av_input, NULL) < 0) {
 	(*out) << "AVHandler: No stream information available" << std::endl;
 	return -1;
     }
 
     for (int i=0; i < av_input->nb_streams; i++) {
-	if (av_input->streams[i]->codec->codec_type == CODEC_TYPE_VIDEO) {
+	if (av_input->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
 	    vstream = av_input->streams[i];
 	    break;
 	}
@@ -173,7 +174,7 @@
     }
 
     for (int i=0; i < av_input->nb_streams; i++) {
-	if (av_input->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO) {
+	if (av_input->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
 	    astream = av_input->streams[i];
 	    break;
 	}
@@ -192,7 +193,7 @@
     if (codec->capabilities & CODEC_CAP_TRUNCATED)
 	vstream->codec->flags |= CODEC_FLAG_TRUNCATED;
 
-    if (avcodec_open(vstream->codec, codec) < 0) {
+    if (avcodec_open2(vstream->codec, codec, NULL) < 0) {
 	(*out) << "AVHandler: Cannot open codec " << codec_name << std::endl;
 	vstream->codec->codec = NULL;
 	return -1;
@@ -204,9 +205,9 @@
     width = vstream->codec->width;
     height = vstream->codec->height;
 
-    title = av_input->title;
-    author = av_input->author;
-    comment = av_input->comment;
+    // FIXME: title = av_input->title;
+    // FIXME: author = av_input->author;
+    // FIXME: comment = av_input->comment;
 
     rgbframe = create_frame(PIX_FMT_RGB24);
     if (!rgbframe) return -1;
@@ -258,7 +259,7 @@
 	if (c->coded_frame)
 	    pkt.pts = c->coded_frame->pts;
 	if (c->coded_frame && c->coded_frame->key_frame)
-	    pkt.flags |= PKT_FLAG_KEY;
+	    pkt.flags |= AV_PKT_FLAG_KEY;
 	/// XXX FIXME XXX does this ensure that the first frame is always a key frame?
 	
 	if (av_write_frame(av_output, &pkt) != 0) {
@@ -296,7 +297,8 @@
        	(*out) << "AVHandler: Error seeking to " << target_timestamp << std::endl;
        	return -1;
     }
-    cc->hurry_up = 1;
+    // http://ffmpeg.org/pipermail/ffmpeg-cvslog/2011-April/035933.html
+    // FIXME: deprecated: cc->hurry_up = 1;
 
     // Flush stream buffers after seek
     avcodec_flush_buffers(cc);
@@ -324,14 +326,14 @@
 		return -1;
 	    }
 
-	    if (url_feof(av_input->pb)) {
+	    if (av_input->pb->eof_reached) {
 		(*out) << "AVHandler: EOF reached" << std::endl;
 	    }
 	}
 
 	// Decode the packet into a frame
 	int frameFinished;
-	if (avcodec_decode_video(cc, frame, &frameFinished, packet.data, packet.size) < 0) {
+    if (avcodec_decode_video2(cc, frame, &frameFinished, &packet) < 0) {
 	    (*out) << "AVHandler: Error decoding video stream" << std::endl;
 	    av_free_packet(&packet);
 	    av_free(frame); frame = NULL;
@@ -342,7 +344,8 @@
 	    current_timestamp = (uint64_t)(vstream->cur_dts * AV_TIME_BASE * (long double)stream_time_base);
 	}
     }
-    cc->hurry_up = 0;
+    // http://ffmpeg.org/pipermail/ffmpeg-cvslog/2011-April/035933.html
+    // FIXME: deprecated: cc->hurry_up = 0;
 
     SwsContext *sc = sws_getContext(cc->width, cc->height, cc->pix_fmt, 
 				    cc->width, cc->height, PIX_FMT_BGR24, 
@@ -361,9 +364,9 @@
     (*out) << "Supported file formats:" << std::endl;
     av_register_all();
 
-    AVOutputFormat *ofmt;
-    for (ofmt = first_oformat; ofmt != NULL; ofmt = ofmt->next) {
-	(*out) << ofmt->name << " ";
+    AVOutputFormat *ofmt = NULL;
+    while (NULL != (ofmt = av_oformat_next(ofmt))) {
+    	(*out) << ofmt->name << " ";
     }
     (*out) << std::endl << std::endl;
 }
@@ -375,7 +378,7 @@
 
     AVCodec *codec;
     for (codec = av_codec_next(0); codec != NULL; codec = av_codec_next(codec)) {
-	if ((codec->type == CODEC_TYPE_VIDEO) &&
+	if ((codec->type == AVMEDIA_TYPE_VIDEO) &&
 	    (codec->encode)) {	    
 	    (*out) << codec->name << " ";
 	}
@@ -386,8 +389,9 @@
 int
 AVHandler::add_video_stream() {
     AVCodecContext *cc;
-    
-    vstream = av_new_stream(av_output, 0);
+
+    // FIXME: vstream = avformat_new_stream(av_output, av_find_default_stream_index(av_output));
+    vstream = avformat_new_stream(av_output, NULL);
     if (!vstream) {
 	(*out) << "AVHandler: error opening video output stream" << std::endl;
 	return -1;
@@ -395,8 +399,8 @@
     
     cc = vstream->codec;
 
-    cc->codec_type = CODEC_TYPE_VIDEO;
-    
+    cc->codec_type = AVMEDIA_TYPE_VIDEO;
+
     cc->bit_rate = bitrate;
     cc->width = width;
     cc->height = height;
@@ -426,7 +430,7 @@
 	return -1;
     }
 
-    if (avcodec_open(cc, codec) < 0) {
+    if (avcodec_open2(cc, codec, NULL) < 0) {
 	(*out) << "AVHandler: cannot open codec" << std::endl;
 	cc->codec = NULL;
 	return -1;
diff -ur video-1.0.2/src/AVHandler.h video-new/src/AVHandler.h
--- video-1.0.2/src/AVHandler.h	2009-05-08 15:17:36.000000000 +0200
+++ video-new/src/AVHandler.h	2012-09-26 22:29:32.000000000 +0200
@@ -27,8 +27,11 @@
 
 #define VIDEO_OUTBUF_SIZE 200000
 
+// FIXME: should define -D__STDC_CONSTANT_MACROS instead of the following
 #define INT64_C
+#define UINT64_C
 #define __STDC_CONSTANT_MACROS
+
 #include <errno.h>
 extern "C" {
 #if defined (HAVE_FFMPEG_AVFORMAT_H)
@@ -165,7 +168,7 @@
 
   unsigned int get_total_frames() const {
     if (vstream) {
-      return (unsigned int)((double)framerate * vstream->duration / AV_TIME_BASE);
+        return (unsigned int) vstream->nb_frames;
     } else {
       return 0;
     }
@@ -173,7 +176,7 @@
 
   unsigned int get_filesize() const {
     if (av_input) {
-      return av_input->file_size;
+      return avio_size(av_input->pb);
     } else {
       return 0;
     }
diff -ur video-1.0.2/src/aviinfo.cc video-new/src/aviinfo.cc
--- video-1.0.2/src/aviinfo.cc	2009-05-08 15:17:36.000000000 +0200
+++ video-new/src/aviinfo.cc	2012-09-26 16:50:57.000000000 +0200
@@ -66,6 +66,7 @@
     av.set_log(&octave_stdout);
 
     if (av.setup_read() != 0) {
+	error("aviread: AVHandler setup failed");
 	return retval;
     }
 
diff -ur video-1.0.2/src/oct-avifile.cc video-new/src/oct-avifile.cc
--- video-1.0.2/src/oct-avifile.cc	2012-10-05 12:51:44.736740442 +0200
+++ video-new/src/oct-avifile.cc	2012-10-05 12:53:45.004737755 +0200
@@ -56,10 +56,12 @@
 void
 Avifile::addframe(const NDArray &f) {
     if (frames == 0) {
-	if ( (f.columns() % 2 != 0) || (f.rows() % 2 != 0) ) {
-	    error("avifile: matrix dimensions must be multiple of two");
-	    return;
-	}
+	// FIXME: this block helps prevent warnings from ffmpeg, but
+	//        doesn't work with many videos.
+	// if ( (f.columns() % 2 != 0) || (f.rows() % 2 != 0) ) {
+	    // error("avifile: matrix dimensions must be multiple of two");
+	    // return;
+	// }
 
 	if ( (f.columns() == 0) || (f.rows() == 0) ) {
 	    error("avifile: matrix must have non-zero dimensions");
------------------------------------------------------------------------------
Don't let slow site performance ruin your business. Deploy New Relic APM
Deploy New Relic app performance management and know exactly
what is happening inside your Ruby, Python, PHP, Java, and .NET app
Try New Relic at no cost today and get our sweet Data Nerd shirt too!
http://p.sf.net/sfu/newrelic-dev2dev
_______________________________________________
Octave-dev mailing list
Octave-dev@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/octave-dev

Reply via email to