src/io/source_avcodec.c: make sure seek position is >= 0
[aubio.git] / src / io / source_avcodec.c
index 9a5201e..4ed6499 100644 (file)
@@ -18,8 +18,7 @@
 
 */
 
-
-#include "config.h"
+#include "aubio_priv.h"
 
 #ifdef HAVE_LIBAV
 
@@ -41,6 +40,7 @@
 // backward compatibility with libavcodec55
 #if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(55,28,1)
 #warning "libavcodec55 is deprecated"
+#define HAVE_AUBIO_LIBAVCODEC_DEPRECATED 1
 #define av_frame_alloc  avcodec_alloc_frame
 #define av_frame_free avcodec_free_frame
 #define av_packet_unref av_free_packet
@@ -477,10 +477,22 @@ uint_t aubio_source_avcodec_seek (aubio_source_avcodec_t * s, uint_t pos) {
   int64_t min_ts = MAX(resampled_pos - 2000, 0);
   int64_t max_ts = MIN(resampled_pos + 2000, INT64_MAX);
   int seek_flags = AVSEEK_FLAG_FRAME | AVSEEK_FLAG_ANY;
-  int ret = avformat_seek_file(s->avFormatCtx, s->selected_stream,
+  int ret = AUBIO_FAIL;
+  if (s->avFormatCtx != NULL && s->avr != NULL) {
+    ret = AUBIO_OK;
+  } else {
+    AUBIO_ERR("source_avcodec: failed seeking in %s (file not opened?)", s->path);
+    return ret;
+  }
+  if ((sint_t)pos < 0) {
+    AUBIO_ERR("source_avcodec: could not seek %s at %d (seeking position"
+       " should be >= 0)\n", s->path, pos);
+    return AUBIO_FAIL;
+  }
+  ret = avformat_seek_file(s->avFormatCtx, s->selected_stream,
       min_ts, resampled_pos, max_ts, seek_flags);
   if (ret < 0) {
-    AUBIO_ERR("Failed seeking to %d in file %s", pos, s->path);
+    AUBIO_ERR("source_avcodec: failed seeking to %d in file %s", pos, s->path);
   }
   // reset read status
   s->eof = 0;
@@ -512,7 +524,9 @@ uint_t aubio_source_avcodec_close(aubio_source_avcodec_t * s) {
   s->avCodecCtx = NULL;
   if (s->avFormatCtx != NULL) {
     avformat_close_input(&s->avFormatCtx);
+#ifndef HAVE_AUBIO_LIBAVCODEC_DEPRECATED // avoid crash on old libavcodec54
     avformat_free_context(s->avFormatCtx);
+#endif
     s->avFormatCtx = NULL;
   }
   av_packet_unref(&s->avPacket);
@@ -529,8 +543,11 @@ void del_aubio_source_avcodec(aubio_source_avcodec_t * s){
   if (s->avFrame != NULL) {
     av_frame_free( &(s->avFrame) );
   }
-  if (s->path) AUBIO_FREE(s->path);
   s->avFrame = NULL;
+  if (s->path) {
+    AUBIO_FREE(s->path);
+  }
+  s->path = NULL;
   AUBIO_FREE(s);
 }