ffmpeg api3 upgrade, rework bs filts, rm faac/d, fixes
authorGood Guy <[email protected]>
Sun, 23 Apr 2017 22:13:37 +0000 (16:13 -0600)
committerGood Guy <[email protected]>
Sun, 23 Apr 2017 22:13:37 +0000 (16:13 -0600)
21 files changed:
cinelerra-5.1/cinelerra/assetedit.C
cinelerra-5.1/cinelerra/bdwrite.C
cinelerra-5.1/cinelerra/ffmpeg.C
cinelerra-5.1/cinelerra/ffmpeg.h
cinelerra-5.1/cinelerra/fileac3.C
cinelerra-5.1/cinelerra/fileac3.h
cinelerra-5.1/cinelerra/filempeg.C
cinelerra-5.1/cinelerra/preferences.C
cinelerra-5.1/cinelerra/ydiff.C
cinelerra-5.1/configure.ac
cinelerra-5.1/ffmpeg/audio/acc256k.pro
cinelerra-5.1/ffmpeg/audio/h265.mp4
cinelerra-5.1/ffmpeg/audio/mp4.qt
cinelerra-5.1/ffmpeg/format/dvd
cinelerra-5.1/libzmpeg3/audio/ac3.C
cinelerra-5.1/thirdparty/src/a52dec.patch1 [new file with mode: 0644]
cinelerra-5.1/thirdparty/src/faac-1.28.tar.xz [deleted file]
cinelerra-5.1/thirdparty/src/faac.patch1 [deleted file]
cinelerra-5.1/thirdparty/src/faac.patch2 [deleted file]
cinelerra-5.1/thirdparty/src/faad2-2.7.tar.xz [deleted file]
cinelerra-5.1/thirdparty/src/ffmpeg.patch3 [deleted file]

index 5b753657f0f1325445597962173fbda4cbdac9b7..3eee273f20ea946e090df7228b71958e4d522b66 100644 (file)
@@ -110,7 +110,7 @@ void AssetEdit::edit_asset(Indexable *indexable)
 
 void AssetEdit::handle_done_event(int result)
 {
-       if( !result ) {
+       if( !result && window->tc_hours_textbox ) {
                changed_params->tcstart = ceil(indexable->get_frame_rate() *
                        (atoi(window->tc_hours_textbox->get_text()) * 3600 +
                         atoi(window->tc_minutes_textbox->get_text()) * 60 +
@@ -225,6 +225,12 @@ AssetEditWindow::AssetEditWindow(MWindow *mwindow, AssetEdit *asset_edit)
        lohi = 0;
        allow_edits = 0;
        detail_thread = 0;
+       tc_hours_textbox = 0;
+       tc_minutes_textbox = 0;
+       tc_seconds_textbox = 0;
+       tc_rest_textbox = 0;
+       win_width = 0;
+       win_height = 0;
 }
 
 
index a85967062f763cd0130f6d8e55372b355cc70e7e..e67f270dae485ae7f3deb146d49404dca2b03ae7 100644 (file)
@@ -1110,17 +1110,18 @@ public:
   int av_idx;
   AVMediaType type;
   AVCodecID codec_id;
+  AVCodecContext *ctx;
   int64_t start_pts;
   int64_t end_pts;
   int64_t last_pts;
   int64_t duration;
 
   stream(AVMediaType ty, int i) {
-    type = ty;  av_idx = i;
+    type = ty;  av_idx = i;  ctx = 0;
     start_pts = INT64_MAX; end_pts = INT64_MIN;
     last_pts = -1;
   }
-  ~stream() {}
+  ~stream() { if( ctx ) avcodec_free_context(&ctx); }
 };
 
 class mark {
@@ -2508,9 +2509,15 @@ static int field_probe(AVFormatContext *fmt_ctx, AVStream *st)
 {
   AVDictionary *copts = 0;
   //av_dict_copy(&copts, opts, 0);
-  AVCodecID codec_id = st->codec->codec_id;
+  AVCodecID codec_id = st->codecpar->codec_id;
   AVCodec *decoder = avcodec_find_decoder(codec_id);
-  if( avcodec_open2(st->codec, decoder, &copts) < 0 ) {
+  AVCodecContext *ctx = avcodec_alloc_context3(decoder);
+  if( !ctx ) {
+    fprintf(stderr,"codec alloc failed\n");
+    return -1;
+  }
+  avcodec_parameters_to_context(ctx, st->codecpar);
+  if( avcodec_open2(ctx, decoder, &copts) < 0 ) {
     fprintf(stderr,"codec open failed\n");
     return -1;
   }
@@ -2525,22 +2532,24 @@ static int field_probe(AVFormatContext *fmt_ctx, AVStream *st)
     int ret = av_read_frame(fmt_ctx, &ipkt);
     if( ret == AVERROR_EOF ) break;
     if( ret != 0 ) continue;
-    if( !ipkt.data ) continue;
     if( ipkt.stream_index != st->index ) continue;
-    while( ipkt.size > 0 ) {
-      int got_frame = 0;
-      ret = avcodec_decode_video2(st->codec, ipic, &got_frame, &ipkt);
-      if( ret <= 0 ) break;
-      if( got_frame ) {
-        ilaced = ipic->interlaced_frame ? 1 : 0;
-        break;
-      }
-      ipkt.data += ret;
-      ipkt.size -= ret;
+    if( !ipkt.data || !ipkt.size ) continue;
+    ret = avcodec_send_packet(ctx, &ipkt);
+    if( ret < 0 ) {
+      fprintf(stderr, "avcodec_send_packet failed\n");
+      break;
     }
+    ret = avcodec_receive_frame(ctx, ipic);
+    if( ret >= 0 ) {
+      ilaced = ipic->interlaced_frame ? 1 : 0;
+      break;
+    }
+    if( ret != AVERROR(EAGAIN) )
+      fprintf(stderr, "avcodec_receive_frame failed %d\n", ret);
   }
   av_packet_unref(&ipkt);
   av_frame_free(&ipic);
+  avcodec_free_context(&ctx);
   return ilaced;
 }
 
@@ -2565,7 +2574,7 @@ int media_info::scan()
   int ep_pid = -1;
   for( int i=0; ret>=0 && i<(int)fmt_ctx->nb_streams; ++i ) {
     AVStream *st = fmt_ctx->streams[i];
-    AVMediaType type = st->codec->codec_type;
+    AVMediaType type = st->codecpar->codec_type;
     switch( type ) {
     case AVMEDIA_TYPE_VIDEO: break;
     case AVMEDIA_TYPE_AUDIO: break;
@@ -2574,7 +2583,13 @@ int media_info::scan()
     }
     stream *s = new stream(type, i);
     s->pid = st->id;
-    AVCodecID codec_id = st->codec->codec_id;
+    AVCodecID codec_id = st->codecpar->codec_id;
+    AVCodec *decoder = avcodec_find_decoder(codec_id);
+    s->ctx = avcodec_alloc_context3(decoder);
+    if( !s->ctx ) {
+      fprintf(stderr, "avcodec_alloc_context failed\n");
+      continue;
+    }
     switch( type ) {
     case AVMEDIA_TYPE_VIDEO: {
       if( ep_pid < 0 ) ep_pid = st->id;
@@ -2584,17 +2599,17 @@ int media_info::scan()
         fprintf(stderr, "interlace probe failed\n");
         exit(1);
       }
-      s->format = bd_video_format(st->codec->width, st->codec->height, ilace);
-      s->rate = bd_video_rate(!st->codec->framerate.den ? 0 :
-               (double)st->codec->framerate.num / st->codec->framerate.den);
-      s->aspect = bd_aspect_ratio(st->codec->width, st->codec->height,
+      s->format = bd_video_format(st->codecpar->width, st->codecpar->height, ilace);
+      AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0);
+      s->rate = bd_video_rate(!framerate.den ? 0 : (double)framerate.num / framerate.den);
+      s->aspect = bd_aspect_ratio(st->codecpar->width, st->codecpar->height,
                !st->sample_aspect_ratio.num || !st->sample_aspect_ratio.den ? 1. :
                 (double)st->sample_aspect_ratio.num / st->sample_aspect_ratio.den);
       break; }
     case AVMEDIA_TYPE_AUDIO: {
       s->coding_type = bd_stream_type(codec_id);
-      s->format = bd_audio_format(st->codec->channels);
-      s->rate = bd_audio_rate(st->codec->sample_rate);
+      s->format = bd_audio_format(st->codecpar->channels);
+      s->rate = bd_audio_rate(st->codecpar->sample_rate);
       strcpy((char*)s->lang, "eng");
       break; }
     case AVMEDIA_TYPE_SUBTITLE: {
@@ -2613,9 +2628,8 @@ int media_info::scan()
     s->duration = av_rescale_q(st->duration, st->time_base, clk45k);
     streams.append(s);
 
-    AVCodec *decoder = avcodec_find_decoder(codec_id);
     AVDictionary *copts = 0;
-    ret = avcodec_open2(st->codec, decoder, &copts);
+    ret = avcodec_open2(s->ctx, decoder, &copts);
   }
   if( ep_pid < 0 )
     ep_pid = fmt_ctx->nb_streams > 0 ? fmt_ctx->streams[0]->id : 0;
@@ -2629,7 +2643,7 @@ int media_info::scan()
     pgm->duration = 0;
     for( int jj=0; jj<streams.size(); ++jj ) {
       AVStream *st = fmt_ctx->streams[jj];
-      AVMediaType type = st->codec->codec_type;
+      AVMediaType type = st->codecpar->codec_type;
       switch( type ) {
       case AVMEDIA_TYPE_VIDEO:
       case AVMEDIA_TYPE_AUDIO:
@@ -2654,7 +2668,7 @@ int media_info::scan()
     for( int jj=0; jj<(int)pgrm->nb_stream_indexes; ++jj ) {
       int av_idx = pgrm->stream_index[jj];
       AVStream *st = fmt_ctx->streams[av_idx];
-      AVMediaType type = st->codec->codec_type;
+      AVMediaType type = st->codecpar->codec_type;
       switch( type ) {
       case AVMEDIA_TYPE_VIDEO:
         if( ep_pid < 0 ) ep_pid = st->id;
@@ -2687,8 +2701,8 @@ int media_info::scan()
   if( ret >= 0 )
     ret = scan(fmt_ctx);
 
-  for( int i=0; i<(int)fmt_ctx->nb_streams; ++i )
-    avcodec_close(fmt_ctx->streams[i]->codec);
+  for( int i=0; i<(int)streams.size(); ++i )
+    avcodec_close(streams[i]->ctx);
   avformat_close_input(&fmt_ctx);
 
   return ret;
index 44a337e60e7e4e84841a71a3a5f3d7db2a460a6c..70ccc272f1d16156a6634c43741f63ab1e7bfb4d 100644 (file)
@@ -234,6 +234,7 @@ FFStream::FFStream(FFMPEG *ffmpeg, AVStream *st, int fidx)
        this->fidx = fidx;
        frm_lock = new Mutex("FFStream::frm_lock");
        fmt_ctx = 0;
+       avctx = 0;
        filter_graph = 0;
        buffersrc_ctx = 0;
        buffersink_ctx = 0;
@@ -245,17 +246,19 @@ FFStream::FFStream(FFMPEG *ffmpeg, AVStream *st, int fidx)
        flushed = 0;
        need_packet = 1;
        frame = fframe = 0;
+       bsfc = 0;
 }
 
 FFStream::~FFStream()
 {
-       if( reading > 0 || writing > 0 ) avcodec_close(st->codec);
+       if( reading > 0 || writing > 0 ) avcodec_close(avctx);
+       if( avctx ) avcodec_free_context(&avctx);
        if( fmt_ctx ) avformat_close_input(&fmt_ctx);
+       if( bsfc ) av_bsf_free(&bsfc);
        while( frms.first ) frms.remove(frms.first);
        if( filter_graph ) avfilter_graph_free(&filter_graph);
        if( frame ) av_frame_free(&frame);
        if( fframe ) av_frame_free(&fframe);
-       bsfilter.remove_all_objects();
        delete frm_lock;
 }
 
@@ -308,10 +311,18 @@ int FFStream::decode_activate()
                        st = fmt_ctx->streams[fidx];
                        load_markers();
                }
-               if( ret >= 0 ) {
-                       AVCodecID codec_id = st->codec->codec_id;
+               if( ret >= 0 && st != 0 ) {
+                       AVCodecID codec_id = st->codecpar->codec_id;
                        AVCodec *decoder = avcodec_find_decoder(codec_id);
-                       ret = avcodec_open2(st->codec, decoder, &copts);
+                       avctx = avcodec_alloc_context3(decoder);
+                       if( !avctx ) {
+                               eprintf(_("cant allocate codec context\n"));
+                               ret = AVERROR(ENOMEM);
+                       }
+                       if( ret >= 0 ) {
+                               avcodec_parameters_to_context(avctx, st->codecpar);
+                               ret = avcodec_open2(avctx, decoder, &copts);
+                       }
                        if( ret >= 0 )
                                reading = 1;
                        else
@@ -331,10 +342,7 @@ int FFStream::read_packet()
        int ret = av_read_frame(fmt_ctx, ipkt);
        if( ret < 0 ) {
                st_eof(1);
-               if( ret == AVERROR_EOF ) {
-                       ipkt->stream_index = st->index;
-                       return 0;
-               }
+               if( ret == AVERROR_EOF ) return 0;
                ff_err(ret, "FFStream::read_packet: av_read_frame failed\n");
                flushed = 1;
                return -1;
@@ -346,36 +354,35 @@ int FFStream::decode(AVFrame *frame)
 {
        int ret = 0;
        int retries = MAX_RETRY;
-       int got_frame = 0;
 
-       while( ret >= 0 && !flushed && --retries >= 0 && !got_frame ) {
+       while( ret >= 0 && !flushed && --retries >= 0 ) {
                if( need_packet ) {
-                       need_packet = 0;
                        if( (ret=read_packet()) < 0 ) break;
-               }
-               if( ipkt->stream_index == st->index ) {
-                       while( (ipkt->size > 0 || !ipkt->data) && !got_frame ) {
-                               ret = decode_frame(ipkt, frame, got_frame);
-                               if( ret < 0 ) need_packet = 1;
-                               if( ret <= 0 || !ipkt->data ) break;
-                               ipkt->data += ret;
-                               ipkt->size -= ret;
+                       AVPacket *pkt = ret > 0 ? (AVPacket*)ipkt : 0;
+                       if( pkt ) {
+                               if( pkt->stream_index != st->index ) continue;
+                               if( !pkt->data | !pkt->size ) continue;
+                       }
+                       if( (ret=avcodec_send_packet(avctx, pkt)) < 0 ) {
+                               ff_err(ret, "FFStream::decode: avcodec_send_packet failed\n");
+                               break;
                        }
+                       need_packet = 0;
                        retries = MAX_RETRY;
                }
-               if( !got_frame ) {
+               if( (ret=decode_frame(frame)) > 0 ) break;
+               if( !ret ) {
                        need_packet = 1;
                        flushed = st_eof();
                }
        }
 
-       if( retries < 0 )
+       if( retries < 0 ) {
                fprintf(stderr, "FFStream::decode: Retry limit\n");
-       if( ret >= 0 )
-               ret = got_frame;
-       else
+               ret = 0;
+       }
+       if( ret < 0 )
                fprintf(stderr, "FFStream::decode: failed\n");
-
        return ret;
 }
 
@@ -420,24 +427,56 @@ int FFStream::read_frame(AVFrame *frame)
 
 int FFStream::write_packet(FFPacket &pkt)
 {
-       bs_filter(pkt);
-       av_packet_rescale_ts(pkt, st->codec->time_base, st->time_base);
-       pkt->stream_index = st->index;
-       return av_interleaved_write_frame(ffmpeg->fmt_ctx, pkt);
+       int ret = 0;
+       if( !bsfc ) {
+               av_packet_rescale_ts(pkt, avctx->time_base, st->time_base);
+               pkt->stream_index = st->index;
+               ret = av_interleaved_write_frame(ffmpeg->fmt_ctx, pkt);
+       }
+       else {
+               ret = av_bsf_send_packet(bsfc, pkt);
+               while( ret >= 0 ) {
+                       FFPacket bs;
+                       if( (ret=av_bsf_receive_packet(bsfc, bs)) < 0 ) {
+                               if( ret == AVERROR(EAGAIN) ) return 0;
+                               if( ret == AVERROR_EOF ) return -1;
+                               break;
+                       }
+                       av_packet_rescale_ts(bs, avctx->time_base, st->time_base);
+                       bs->stream_index = st->index;
+                       ret = av_interleaved_write_frame(ffmpeg->fmt_ctx, bs);
+               }
+       }
+       if( ret < 0 )
+               ff_err(ret, "FFStream::write_packet: write packet failed\n");
+       return ret;
+}
+
+int FFStream::encode_frame(AVFrame *frame)
+{
+       int pkts = 0, ret = 0;
+       for( int retry=100; --retry>=0; ) {
+               if( frame || !pkts )
+                       ret = avcodec_send_frame(avctx, frame);
+               if( !ret && frame ) return pkts;
+               if( ret < 0 && ret != AVERROR(EAGAIN) ) break;
+               FFPacket opkt;
+               ret = avcodec_receive_packet(avctx, opkt);
+               if( !frame && ret == AVERROR_EOF ) return pkts;
+               if( ret < 0 ) break;
+               ret = write_packet(opkt);
+               if( ret < 0 ) break;
+               ++pkts;
+       }
+       ff_err(ret, "FFStream::encode_frame: encode failed\n");
+       return -1;
 }
 
 int FFStream::flush()
 {
        if( writing < 0 )
                return -1;
-       int ret = 0;
-       while( ret >= 0 ) {
-               FFPacket pkt;
-               int got_packet = 0;
-               ret = encode_frame(pkt, 0, got_packet);
-               if( ret < 0 || !got_packet ) break;
-               ret = write_packet(pkt);
-       }
+       int ret = encode_frame(0);
        if( ret < 0 )
                ff_err(ret, "FFStream::flush");
        return ret >= 0 ? 0 : 1;
@@ -448,7 +487,7 @@ int FFStream::seek(int64_t no, double rate)
        int64_t tstmp = -INT64_MAX+1;
 // default ffmpeg native seek
        int npkts = 1;
-       int64_t pos = no, plmt = -1;
+       int64_t pos = no, pkt_pos = -1;
        IndexMarks *index_markers = get_markers();
        if( index_markers && index_markers->size() > 1 ) {
                IndexMarks &marks = *index_markers;
@@ -458,32 +497,56 @@ int FFStream::seek(int64_t no, double rate)
                if( no-n < 30*rate ) {
                        if( n < 0 ) n = 0;
                        pos = n;
-                       if( i < marks.size() ) plmt = marks[i].pos;
+                       if( i < marks.size() ) pkt_pos = marks[i].pos;
                        npkts = MAX_RETRY;
                }
        }
-       if( pos > 0 ) {
+       if( pos > 0 && st->time_base.num > 0 ) {
                double secs = pos / rate;
                tstmp = secs * st->time_base.den / st->time_base.num;
                if( nudge != AV_NOPTS_VALUE ) tstmp += nudge;
        }
-       int ret = avformat_seek_file(fmt_ctx, st->index,
-               -INT64_MAX, tstmp, INT64_MAX, AVSEEK_FLAG_ANY);
-       if( ret >= 0 ) {
-               avcodec_flush_buffers(st->codec);
-               ipkt.finit();  ipkt.init();
+       avcodec_flush_buffers(avctx);
+       avformat_flush(fmt_ctx);
+#if 0
+       int64_t seek = tstmp;
+       int flags = AVSEEK_FLAG_ANY;
+       if( !(fmt_ctx->iformat->flags & AVFMT_NO_BYTE_SEEK) && pkt_pos >= 0 ) {
+               seek = pkt_pos;
+               flags = AVSEEK_FLAG_BYTE;
+       }
+        int ret = avformat_seek_file(fmt_ctx, st->index, -INT64_MAX, seek, INT64_MAX, flags);
+#else
+        int ret = av_seek_frame(fmt_ctx, st->index, tstmp, AVSEEK_FLAG_ANY);
+#endif
+       int retry = MAX_RETRY;
+       while( ret >= 0 ) {
                need_packet = 0;  flushed = 0;
                seeked = 1;  st_eof(0);
-// read up to retry packets, limited to npkts in stream, and not past pkt.pos plmt
-               for(;;) {
+// read up to retry packets, limited to npkts in stream, and not pkt.pos past pkt_pos
+               while( --retry >= 0 ) {
                        if( read_packet() <= 0 ) { ret = -1;  break; }
-                       if( plmt >= 0 && ipkt->pos >= plmt ) break;
                        if( ipkt->stream_index != st->index ) continue;
+                       if( !ipkt->data || !ipkt->size ) continue;
+                       if( pkt_pos >= 0 && ipkt->pos >= pkt_pos ) break;
                        if( --npkts <= 0 ) break;
                        int64_t pkt_ts = ipkt->dts != AV_NOPTS_VALUE ? ipkt->dts : ipkt->pts;
                        if( pkt_ts == AV_NOPTS_VALUE ) continue;
                        if( pkt_ts >= tstmp ) break;
                }
+               if( retry < 0 ) {
+                       fprintf(stderr,"FFStream::seek: retry limit, pos=%jd tstmp=%jd\n",pos,tstmp);
+                       ret = -1;
+               }
+               if( ret < 0 ) break;
+               ret = avcodec_send_packet(avctx, ipkt);
+               if( !ret ) break;
+//some codecs need more than one pkt to resync
+               if( ret == AVERROR_INVALIDDATA ) ret = 0;
+               if( ret < 0 ) {
+                       ff_err(ret, "FFStream::avcodec_send_packet failed\n");
+                       break;
+               }
        }
        if( ret < 0 ) {
 //printf("** seek fail %ld, %ld\n", pos, tstmp);
@@ -561,42 +624,33 @@ int FFAudioStream::load_history(uint8_t **data, int len)
        return len;
 }
 
-int FFAudioStream::decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame)
+int FFAudioStream::decode_frame(AVFrame *frame)
 {
        int first_frame = seeked;  seeked = 0;
-       int ret = avcodec_decode_audio4(st->codec, frame, &got_frame, pkt);
+       int ret = avcodec_receive_frame(avctx, frame);
        if( ret < 0 ) {
-               if( first_frame ) return 0;
+               if( first_frame || ret == AVERROR(EAGAIN) ) return 0;
+               if( ret == AVERROR_EOF ) { st_eof(1); return 0; }
                ff_err(ret, "FFAudioStream::decode_frame: Could not read audio frame\n");
                return -1;
        }
-       if( got_frame ) {
-               int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
-               if( pkt_ts != AV_NOPTS_VALUE )
-                       curr_pos = ffmpeg->to_secs(pkt_ts - nudge, st->time_base) * sample_rate + 0.5;
-       }
-       return ret;
+       int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
+       if( pkt_ts != AV_NOPTS_VALUE )
+               curr_pos = ffmpeg->to_secs(pkt_ts - nudge, st->time_base) * sample_rate + 0.5;
+       return 1;
 }
 
 int FFAudioStream::encode_activate()
 {
        if( writing >= 0 ) return writing;
-       AVCodecContext *ctx = st->codec;
-       frame_sz = ctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
-               10000 : ctx->frame_size;
+       frame_sz = avctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
+               10000 : avctx->frame_size;
        return FFStream::encode_activate();
 }
 
-int FFAudioStream::nb_samples()
-{
-       AVCodecContext *ctx = st->codec;
-       return ctx->codec->capabilities & CODEC_CAP_VARIABLE_FRAME_SIZE ?
-               10000 : ctx->frame_size;
-}
-
 int64_t FFAudioStream::load_buffer(double ** const sp, int len)
 {
-       reserve(len+1, st->codec->channels);
+       reserve(len+1, st->codecpar->channels);
        for( int ch=0; ch<nch; ++ch )
                write(sp[ch], len, ch);
        return put_inp(len);
@@ -614,11 +668,10 @@ int FFAudioStream::in_history(int64_t pos)
 
 int FFAudioStream::init_frame(AVFrame *frame)
 {
-       AVCodecContext *ctx = st->codec;
        frame->nb_samples = frame_sz;
-       frame->format = ctx->sample_fmt;
-       frame->channel_layout = ctx->channel_layout;
-       frame->sample_rate = ctx->sample_rate;
+       frame->format = avctx->sample_fmt;
+       frame->channel_layout = avctx->channel_layout;
+       frame->sample_rate = avctx->sample_rate;
        int ret = av_frame_get_buffer(frame, 0);
        if (ret < 0)
                ff_err(ret, "FFAudioStream::init_frame: av_frame_get_buffer failed\n");
@@ -654,7 +707,7 @@ int FFAudioStream::load(int64_t pos, int len)
 int FFAudioStream::audio_seek(int64_t pos)
 {
        if( decode_activate() < 0 ) return -1;
-       if( !st->codec || !st->codec->codec ) return -1;
+       if( !st->codecpar ) return -1;
        if( in_history(pos) ) return 0;
        if( pos == curr_pos ) return 0;
        reset_history();  mbsz = 0;
@@ -693,14 +746,9 @@ int FFAudioStream::encode(double **samples, int len)
        return ret >= 0 ? 0 : 1;
 }
 
-int FFAudioStream::encode_frame(AVPacket *pkt, AVFrame *frame, int &got_packet)
+int FFAudioStream::encode_frame(AVFrame *frame)
 {
-       int ret = avcodec_encode_audio2(st->codec, pkt, frame, &got_packet);
-       if( ret < 0 ) {
-               ff_err(ret, "FFAudioStream::encode_frame: encode audio failed\n");
-               return -1;
-       }
-       return ret;
+       return FFStream::encode_frame(frame);
 }
 
 void FFAudioStream::load_markers()
@@ -734,24 +782,21 @@ FFVideoStream::~FFVideoStream()
 {
 }
 
-int FFVideoStream::decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame)
+int FFVideoStream::decode_frame(AVFrame *frame)
 {
        int first_frame = seeked;  seeked = 0;
-       int ret = avcodec_decode_video2(st->codec, frame, &got_frame, pkt);
+       int ret = avcodec_receive_frame(avctx, frame);
        if( ret < 0 ) {
-               if( first_frame ) return 0;
+               if( first_frame || ret == AVERROR(EAGAIN) ) return 0;
+               if( ret == AVERROR(EAGAIN) ) return 0;
+               if( ret == AVERROR_EOF ) { st_eof(1); return 0; }
                ff_err(ret, "FFVideoStream::decode_frame: Could not read video frame\n");
                return -1;
        }
-       else // this is right out of ffplay, looks questionable ???
-               ret = pkt->size;
-
-       if( got_frame ) {
-               int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
-               if( pkt_ts != AV_NOPTS_VALUE )
-                       curr_pos = ffmpeg->to_secs(pkt_ts - nudge, st->time_base) * frame_rate + 0.5;
-       }
-       return ret;
+       int64_t pkt_ts = av_frame_get_best_effort_timestamp(frame);
+       if( pkt_ts != AV_NOPTS_VALUE )
+               curr_pos = ffmpeg->to_secs(pkt_ts - nudge, st->time_base) * frame_rate + 0.5;
+       return 1;
 }
 
 int FFVideoStream::load(VFrame *vframe, int64_t pos)
@@ -778,10 +823,10 @@ int FFVideoStream::load(VFrame *vframe, int64_t pos)
 int FFVideoStream::video_seek(int64_t pos)
 {
        if( decode_activate() < 0 ) return -1;
-       if( !st->codec || !st->codec->codec ) return -1;
+       if( !st->codecpar ) return -1;
        if( pos == curr_pos-1 && !seeked ) return 0;
 // if close enough, just read up to current
-       int gop = st->codec->gop_size;
+       int gop = avctx->gop_size;
        if( gop < 4 ) gop = 4;
        if( gop > 64 ) gop = 64;
        int read_limit = curr_pos + 3*gop;
@@ -793,10 +838,9 @@ int FFVideoStream::video_seek(int64_t pos)
 
 int FFVideoStream::init_frame(AVFrame *picture)
 {
-       AVCodecContext *ctx = st->codec;
-       picture->format = ctx->pix_fmt;
-       picture->width  = ctx->width;
-       picture->height = ctx->height;
+       picture->format = avctx->pix_fmt;
+       picture->width  = avctx->width;
+       picture->height = avctx->height;
        int ret = av_frame_get_buffer(picture, 32);
        return ret;
 }
@@ -823,18 +867,13 @@ int FFVideoStream::encode(VFrame *vframe)
        return ret >= 0 ? 0 : 1;
 }
 
-int FFVideoStream::encode_frame(AVPacket *pkt, AVFrame *frame, int &got_packet)
+int FFVideoStream::encode_frame(AVFrame *frame)
 {
        if( frame ) {
                frame->interlaced_frame = interlaced;
                frame->top_field_first = top_field_first;
        }
-       int ret = avcodec_encode_video2(st->codec, pkt, frame, &got_packet);
-       if( ret < 0 ) {
-               ff_err(ret, "FFVideoStream::encode_frame: encode video failed\n");
-               return -1;
-       }
-       return ret;
+       return FFStream::encode_frame(frame);
 }
 
 AVPixelFormat FFVideoConvert::color_model_to_pix_fmt(int color_model)
@@ -1344,23 +1383,23 @@ void FFMPEG::set_asset_format(Asset *asset, const char *text)
 }
 
 int FFMPEG::get_encoder(const char *options,
-               char *format, char *codec, char *bsfilter, char *bsargs)
+               char *format, char *codec, char *bsfilter)
 {
        FILE *fp = fopen(options,"r");
        if( !fp ) {
                eprintf(_("options open failed %s\n"),options);
                return 1;
        }
-       if( get_encoder(fp, format, codec, bsfilter, bsargs) )
+       if( get_encoder(fp, format, codec, bsfilter) )
                eprintf(_("format/codec not found %s\n"), options);
        fclose(fp);
        return 0;
 }
 
 int FFMPEG::get_encoder(FILE *fp,
-               char *format, char *codec, char *bsfilter, char *bsargs)
+               char *format, char *codec, char *bsfilter)
 {
-       format[0] = codec[0] = bsfilter[0] = bsargs[0] = 0;
+       format[0] = codec[0] = bsfilter[0] = 0;
        char line[BCTEXTLEN];
        if( !fgets(line, sizeof(line), fp) ) return 1;
        line[sizeof(line)-1] = 0;
@@ -1368,8 +1407,12 @@ int FFMPEG::get_encoder(FILE *fp,
        char *cp = codec;
        while( *cp && *cp != '|' ) ++cp;
        if( !*cp ) return 0;
-       if( scan_option_line(cp+1, bsfilter, bsargs) ) return 1;
-       do { *cp-- = 0; } while( cp>=codec && (*cp==' ' || *cp == '\t' ) );
+       char *bp = cp;
+       do { *bp-- = 0; } while( bp>=codec && (*bp==' ' || *bp == '\t' ) );
+       while( *++cp && (*cp==' ' || *cp == '\t') );
+       bp = bsfilter;
+       for( int i=BCTEXTLEN; --i>0 && *cp; ) *bp++ = *cp++;
+       *bp = 0;
        return 0;
 }
 
@@ -1487,17 +1530,19 @@ int FFMPEG::info(char *text, int len)
        decode_activate();
 #define report(s...) do { int n = snprintf(cp,len,s); cp += n;  len -= n; } while(0)
        char *cp = text;
+       report("format: %s\n",fmt_ctx->iformat->name);
        if( ffvideo.size() > 0 )
                report("\n%d video stream%s\n",ffvideo.size(), ffvideo.size()!=1 ? "s" : "");
        for( int vidx=0; vidx<ffvideo.size(); ++vidx ) {
                FFVideoStream *vid = ffvideo[vidx];
                AVStream *st = vid->st;
-               AVCodecContext *avctx = st->codec;
-               report(_("vid%d (%d),  id 0x%06x:\n"), vid->idx, vid->fidx, avctx->codec_id);
-               const AVCodecDescriptor *desc = avcodec_descriptor_get(avctx->codec_id);
+               AVCodecID codec_id = st->codecpar->codec_id;
+               report(_("vid%d (%d),  id 0x%06x:\n"), vid->idx, vid->fidx, codec_id);
+               const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
                report("  video%d %s", vidx+1, desc ? desc->name : " (unkn)");
                report(" %dx%d %5.2f", vid->width, vid->height, vid->frame_rate);
-               const char *pfn = av_get_pix_fmt_name(avctx->pix_fmt);
+               AVPixelFormat pix_fmt = (AVPixelFormat)st->codecpar->format;
+               const char *pfn = av_get_pix_fmt_name(pix_fmt);
                report(" pix %s\n", pfn ? pfn : "(unkn)");
                double secs = to_secs(st->duration, st->time_base);
                int64_t length = secs * vid->frame_rate + 0.5;
@@ -1514,14 +1559,15 @@ int FFMPEG::info(char *text, int len)
        for( int aidx=0; aidx<ffaudio.size(); ++aidx ) {
                FFAudioStream *aud = ffaudio[aidx];
                AVStream *st = aud->st;
-               AVCodecContext *avctx = st->codec;
-               report(_("aud%d (%d),  id 0x%06x:\n"), aud->idx, aud->fidx, avctx->codec_id);
-               const AVCodecDescriptor *desc = avcodec_descriptor_get(avctx->codec_id);
+               AVCodecID codec_id = st->codecpar->codec_id;
+               report(_("aud%d (%d),  id 0x%06x:\n"), aud->idx, aud->fidx, codec_id);
+               const AVCodecDescriptor *desc = avcodec_descriptor_get(codec_id);
                int nch = aud->channels, ch0 = aud->channel0+1;
                report("  audio%d-%d %s", ch0, ch0+nch-1, desc ? desc->name : " (unkn)");
-               const char *fmt = av_get_sample_fmt_name(avctx->sample_fmt);
+               AVSampleFormat sample_fmt = (AVSampleFormat)st->codecpar->format;
+               const char *fmt = av_get_sample_fmt_name(sample_fmt);
                report(" %s %d", fmt, aud->sample_rate);
-               int sample_bits = av_get_bits_per_sample(avctx->codec_id);
+               int sample_bits = av_get_bits_per_sample(codec_id);
                report(" %dbits\n", sample_bits);
                double secs = to_secs(st->duration, st->time_base);
                int64_t length = secs * aud->sample_rate + 0.5;
@@ -1630,12 +1676,13 @@ int FFMPEG::open_decoder()
        for( int i=0; !ret && i<(int)fmt_ctx->nb_streams; ++i ) {
                AVStream *st = fmt_ctx->streams[i];
                if( st->duration == AV_NOPTS_VALUE ) bad_time = 1;
-               AVCodecContext *avctx = st->codec;
-               const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(avctx->codec_id);
+               AVCodecParameters *avpar = st->codecpar;
+               const AVCodecDescriptor *codec_desc = avcodec_descriptor_get(avpar->codec_id);
                if( !codec_desc ) continue;
-               if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) {
-                       if( avctx->width < 1 ) continue;
-                       if( avctx->height < 1 ) continue;
+               switch( avpar->codec_type ) {
+               case AVMEDIA_TYPE_VIDEO: {
+                       if( avpar->width < 1 ) continue;
+                       if( avpar->height < 1 ) continue;
                        AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0);
                        if( framerate.num < 1 ) continue;
                        has_video = 1;
@@ -1643,8 +1690,8 @@ int FFMPEG::open_decoder()
                        FFVideoStream *vid = new FFVideoStream(this, st, vidx, i);
                        vstrm_index.append(ffidx(vidx, 0));
                        ffvideo.append(vid);
-                       vid->width = avctx->width;
-                       vid->height = avctx->height;
+                       vid->width = avpar->width;
+                       vid->height = avpar->height;
                        vid->frame_rate = !framerate.den ? 0 : (double)framerate.num / framerate.den;
                        double secs = to_secs(st->duration, st->time_base);
                        vid->length = secs * vid->frame_rate;
@@ -1652,35 +1699,38 @@ int FFMPEG::open_decoder()
                        vid->nudge = st->start_time;
                        vid->reading = -1;
                        if( opt_video_filter )
-                               ret = vid->create_filter(opt_video_filter, avctx,avctx);
-               }
-               else if( avctx->codec_type == AVMEDIA_TYPE_AUDIO ) {
-                       if( avctx->channels < 1 ) continue;
-                       if( avctx->sample_rate < 1 ) continue;
+                               ret = vid->create_filter(opt_video_filter, avpar);
+                       break; }
+               case AVMEDIA_TYPE_AUDIO: {
+                       if( avpar->channels < 1 ) continue;
+                       if( avpar->sample_rate < 1 ) continue;
                        has_audio = 1;
                        int aidx = ffaudio.size();
                        FFAudioStream *aud = new FFAudioStream(this, st, aidx, i);
                        ffaudio.append(aud);
                        aud->channel0 = astrm_index.size();
-                       aud->channels = avctx->channels;
+                       aud->channels = avpar->channels;
                        for( int ch=0; ch<aud->channels; ++ch )
                                astrm_index.append(ffidx(aidx, ch));
-                       aud->sample_rate = avctx->sample_rate;
+                       aud->sample_rate = avpar->sample_rate;
                        double secs = to_secs(st->duration, st->time_base);
                        aud->length = secs * aud->sample_rate;
-                       if( avctx->sample_fmt != AV_SAMPLE_FMT_FLT ) {
-                               uint64_t layout = av_get_default_channel_layout(avctx->channels);
+                       if( avpar->format != AV_SAMPLE_FMT_FLT ) {
+                               uint64_t layout = av_get_default_channel_layout(avpar->channels);
                                if( !layout ) layout = ((uint64_t)1<<aud->channels) - 1;
+                               AVSampleFormat sample_format = (AVSampleFormat)avpar->format;
                                aud->resample_context = swr_alloc_set_opts(NULL,
-                                       layout, AV_SAMPLE_FMT_FLT, avctx->sample_rate,
-                                       layout, avctx->sample_fmt, avctx->sample_rate,
+                                       layout, AV_SAMPLE_FMT_FLT, avpar->sample_rate,
+                                       layout, sample_format, avpar->sample_rate,
                                        0, NULL);
                                swr_init(aud->resample_context);
                        }
                        aud->nudge = st->start_time;
                        aud->reading = -1;
                        if( opt_audio_filter )
-                               ret = aud->create_filter(opt_audio_filter, avctx,avctx);
+                               ret = aud->create_filter(opt_audio_filter, avpar);
+                       break; }
+               default: break;
                }
        }
        if( bad_time )
@@ -1737,9 +1787,8 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
        set_option_path(option_path, "%s/%s.opts", type, type);
        read_options(option_path, sopts);
        get_option_path(option_path, type, spec);
-       char format_name[BCSTRLEN], codec_name[BCTEXTLEN];
-       char bsfilter[BCSTRLEN], bsargs[BCTEXTLEN];
-       if( get_encoder(option_path, format_name, codec_name, bsfilter, bsargs) ) {
+       char format_name[BCSTRLEN], codec_name[BCTEXTLEN], bsfilter[BCTEXTLEN];
+       if( get_encoder(option_path, format_name, codec_name, bsfilter) ) {
                eprintf(_("get_encoder failed %s:%s\n"), option_path, filename);
                return 1;
        }
@@ -1752,6 +1801,7 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
        ff_lock("FFMPEG::open_encoder");
        FFStream *fst = 0;
        AVStream *st = 0;
+       AVCodecContext *ctx = 0;
 
        const AVCodecDescriptor *codec_desc = 0;
        AVCodec *codec = avcodec_find_encoder_by_name(codec_name);
@@ -1774,7 +1824,6 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                }
        }
        if( !ret ) {
-               AVCodecContext *ctx = st->codec;
                switch( codec_desc->type ) {
                case AVMEDIA_TYPE_AUDIO: {
                        if( has_audio ) {
@@ -1782,12 +1831,13 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                                ret = 1;
                                break;
                        }
-                       has_audio = 1;
                        if( scan_options(asset->ff_audio_options, sopts, st) ) {
                                eprintf(_("bad audio options %s:%s\n"), codec_name, filename);
                                ret = 1;
                                break;
                        }
+                       has_audio = 1;
+                       ctx = avcodec_alloc_context3(codec);
                        if( asset->ff_audio_bitrate > 0 ) {
                                ctx->bit_rate = asset->ff_audio_bitrate;
                                char arg[BCSTRLEN];
@@ -1797,7 +1847,7 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                        int aidx = ffaudio.size();
                        int fidx = aidx + ffvideo.size();
                        FFAudioStream *aud = new FFAudioStream(this, st, aidx, fidx);
-                       ffaudio.append(aud);  fst = aud;
+                       aud->avctx = ctx;  ffaudio.append(aud);  fst = aud;
                        aud->sample_rate = asset->sample_rate;
                        ctx->channels = aud->channels = asset->channels;
                        for( int ch=0; ch<aud->channels; ++ch )
@@ -1825,12 +1875,13 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                                ret = 1;
                                break;
                        }
-                       has_video = 1;
                        if( scan_options(asset->ff_video_options, sopts, st) ) {
                                eprintf(_("bad video options %s:%s\n"), codec_name, filename);
                                ret = 1;
                                break;
                        }
+                       has_video = 1;
+                       ctx = avcodec_alloc_context3(codec);
                        if( asset->ff_video_bitrate > 0 ) {
                                ctx->bit_rate = asset->ff_video_bitrate;
                                char arg[BCSTRLEN];
@@ -1854,7 +1905,7 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                        int fidx = vidx + ffaudio.size();
                        FFVideoStream *vid = new FFVideoStream(this, st, vidx, fidx);
                        vstrm_index.append(ffidx(vidx, 0));
-                       ffvideo.append(vid);  fst = vid;
+                       vid->avctx = ctx;  ffvideo.append(vid);  fst = vid;
                        vid->width = asset->width;
                        ctx->width = (vid->width+3) & ~3;
                        vid->height = asset->height;
@@ -1882,12 +1933,17 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
        }
        if( !ret ) {
                if( fmt_ctx->oformat->flags & AVFMT_GLOBALHEADER )
-                       st->codec->flags |= CODEC_FLAG_GLOBAL_HEADER;
+                       ctx->flags |= CODEC_FLAG_GLOBAL_HEADER;
 
                av_dict_set(&sopts, "cin_bitrate", 0, 0);
                av_dict_set(&sopts, "cin_quality", 0, 0);
 
-               ret = avcodec_open2(st->codec, codec, &sopts);
+               ret = avcodec_open2(ctx, codec, &sopts);
+               if( ret >= 0 ) {
+                       ret = avcodec_parameters_from_context(st->codecpar, ctx);
+                       if( ret < 0 )
+                               fprintf(stderr, "Could not copy the stream parameters\n");
+               }
                if( ret < 0 ) {
                        ff_err(ret,"FFMPEG::open_encoder");
                        eprintf(_("open failed %s:%s\n"), codec_name, filename);
@@ -1896,9 +1952,15 @@ int FFMPEG::open_encoder(const char *type, const char *spec)
                else
                        ret = 0;
        }
-       if( !ret ) {
-               if( fst && bsfilter[0] )
-                       fst->add_bsfilter(bsfilter, !bsargs[0] ? 0 : bsargs);
+       if( !ret && fst && bsfilter[0] ) {
+               ret = av_bsf_list_parse_str(bsfilter, &fst->bsfc);
+               if( ret < 0 ) {
+                       ff_err(ret,"FFMPEG::open_encoder");
+                       eprintf(_("bitstream filter failed %s:\n%s\n"), filename, bsfilter);
+                       ret = 1;
+               }
+               else
+                       ret = 0;
        }
 
        if( !ret )
@@ -1939,14 +2001,14 @@ int FFMPEG::decode_activate()
                        for( int j=0; j<(int)pgrm->nb_stream_indexes; ++j ) {
                                int fidx = pgrm->stream_index[j];
                                AVStream *st = fmt_ctx->streams[fidx];
-                               AVCodecContext *avctx = st->codec;
-                               if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) {
+                               AVCodecParameters *avpar = st->codecpar;
+                               if( avpar->codec_type == AVMEDIA_TYPE_VIDEO ) {
                                        if( st->start_time == AV_NOPTS_VALUE ) continue;
                                        if( vstart_time < st->start_time )
                                                vstart_time = st->start_time;
                                        continue;
                                }
-                               if( avctx->codec_type == AVMEDIA_TYPE_AUDIO ) {
+                               if( avpar->codec_type == AVMEDIA_TYPE_AUDIO ) {
                                        if( st->start_time == AV_NOPTS_VALUE ) continue;
                                        if( astart_time < st->start_time )
                                                astart_time = st->start_time;
@@ -1960,15 +2022,15 @@ int FFMPEG::decode_activate()
                        for( int j=0; j<(int)pgrm->nb_stream_indexes; ++j ) {
                                int fidx = pgrm->stream_index[j];
                                AVStream *st = fmt_ctx->streams[fidx];
-                               AVCodecContext *avctx = st->codec;
-                               if( avctx->codec_type == AVMEDIA_TYPE_VIDEO ) {
+                               AVCodecParameters *avpar = st->codecpar;
+                               if( avpar->codec_type == AVMEDIA_TYPE_VIDEO ) {
                                        for( int k=0; k<ffvideo.size(); ++k ) {
                                                if( ffvideo[k]->fidx != fidx ) continue;
                                                ffvideo[k]->nudge = nudge;
                                        }
                                        continue;
                                }
-                               if( avctx->codec_type == AVMEDIA_TYPE_AUDIO ) {
+                               if( avpar->codec_type == AVMEDIA_TYPE_AUDIO ) {
                                        for( int k=0; k<ffaudio.size(); ++k ) {
                                                if( ffaudio[k]->fidx != fidx ) continue;
                                                ffaudio[k]->nudge = nudge;
@@ -1982,8 +2044,8 @@ int FFMPEG::decode_activate()
                int nstreams = fmt_ctx->nb_streams;
                for( int i=0; i<nstreams; ++i ) {
                        AVStream *st = fmt_ctx->streams[i];
-                       AVCodecContext *avctx = st->codec;
-                       switch( avctx->codec_type ) {
+                       AVCodecParameters *avpar = st->codecpar;
+                       switch( avpar->codec_type ) {
                        case AVMEDIA_TYPE_VIDEO: {
                                if( st->start_time == AV_NOPTS_VALUE ) continue;
                                int vidx = ffvideo.size();
@@ -2173,16 +2235,12 @@ void FFMPEG::flow_ctl()
 
 int FFMPEG::mux_audio(FFrame *frm)
 {
-       FFPacket pkt;
        FFStream *fst = frm->fst;
-       AVCodecContext *ctx = fst->st->codec;
+       AVCodecContext *ctx = fst->avctx;
        AVFrame *frame = *frm;
        AVRational tick_rate = {1, ctx->sample_rate};
        frame->pts = av_rescale_q(frm->position, tick_rate, ctx->time_base);
-       int got_packet = 0;
-       int ret = fst->encode_frame(pkt, frame, got_packet);
-       if( ret >= 0 && got_packet )
-               ret = fst->write_packet(pkt);
+       int ret = fst->encode_frame(frame);
        if( ret < 0 )
                ff_err(ret, "FFMPEG::mux_audio");
        return ret >= 0 ? 0 : 1;
@@ -2190,14 +2248,10 @@ int FFMPEG::mux_audio(FFrame *frm)
 
 int FFMPEG::mux_video(FFrame *frm)
 {
-       FFPacket pkt;
        FFStream *fst = frm->fst;
        AVFrame *frame = *frm;
        frame->pts = frm->position;
-       int got_packet = 0;
-       int ret = fst->encode_frame(pkt, frame, got_packet);
-       if( ret >= 0 && got_packet )
-               ret = fst->write_packet(pkt);
+       int ret = fst->encode_frame(frame);
        if( ret < 0 )
                ff_err(ret, "FFMPEG::mux_video");
        return ret >= 0 ? 0 : 1;
@@ -2214,7 +2268,7 @@ void FFMPEG::mux()
                        if( fst->frm_count < 3 ) { demand = 1; flow_on(); }
                        FFrame *frm = fst->frms.first;
                        if( !frm ) { if( !done ) return; continue; }
-                       double tm = to_secs(frm->position, fst->st->codec->time_base);
+                       double tm = to_secs(frm->position, fst->avctx->time_base);
                        if( atm < 0 || tm < atm ) { atm = tm;  afrm = frm; }
                }
                for( int i=0; i<ffvideo.size(); ++i ) {  // earliest video
@@ -2222,14 +2276,14 @@ void FFMPEG::mux()
                        if( fst->frm_count < 2 ) { demand = 1; flow_on(); }
                        FFrame *frm = fst->frms.first;
                        if( !frm ) { if( !done ) return; continue; }
-                       double tm = to_secs(frm->position, fst->st->codec->time_base);
+                       double tm = to_secs(frm->position, fst->avctx->time_base);
                        if( vtm < 0 || tm < vtm ) { vtm = tm;  vfrm = frm; }
                }
                if( !demand ) flow_off();
                if( !afrm && !vfrm ) break;
                int v = !afrm ? -1 : !vfrm ? 1 : av_compare_ts(
-                       vfrm->position, vfrm->fst->st->codec->time_base,
-                       afrm->position, afrm->fst->st->codec->time_base);
+                       vfrm->position, vfrm->fst->avctx->time_base,
+                       afrm->position, afrm->fst->avctx->time_base);
                FFrame *frm = v <= 0 ? vfrm : afrm;
                if( frm == afrm ) mux_audio(frm);
                if( frm == vfrm ) mux_video(frm);
@@ -2275,7 +2329,7 @@ int FFMPEG::ff_sample_rate(int stream)
 const char* FFMPEG::ff_audio_format(int stream)
 {
        AVStream *st = ffaudio[stream]->st;
-       AVCodecID id = st->codec->codec_id;
+       AVCodecID id = st->codecpar->codec_id;
        const AVCodecDescriptor *desc = avcodec_descriptor_get(id);
        return desc ? desc->name : _("Unknown");
 }
@@ -2303,7 +2357,7 @@ int FFMPEG::ff_audio_for_video(int vstream, int astream, int64_t &channel_mask)
                for( int j=0;  pidx<0 && j<(int)pgrm->nb_stream_indexes; ++j ) {
                        int st_idx = pgrm->stream_index[j];
                        AVStream *st = fmt_ctx->streams[st_idx];
-                       if( st->codec->codec_type != AVMEDIA_TYPE_VIDEO ) continue;
+                       if( st->codecpar->codec_type != AVMEDIA_TYPE_VIDEO ) continue;
                        if( st_idx == vidx ) pidx = i;
                }
        }
@@ -2314,7 +2368,7 @@ int FFMPEG::ff_audio_for_video(int vstream, int astream, int64_t &channel_mask)
        for( int j=0; j<(int)pgrm->nb_stream_indexes; ++j ) {
                int aidx = pgrm->stream_index[j];
                AVStream *st = fmt_ctx->streams[aidx];
-               if( st->codec->codec_type != AVMEDIA_TYPE_AUDIO ) continue;
+               if( st->codecpar->codec_type != AVMEDIA_TYPE_AUDIO ) continue;
                if( astream > 0 ) { --astream;  continue; }
                int astrm = -1;
                for( int i=0; astrm<0 && i<ffaudio.size(); ++i )
@@ -2367,14 +2421,12 @@ int FFMPEG::ff_set_video_height(int stream, int height)
 
 int FFMPEG::ff_coded_width(int stream)
 {
-       AVStream *st = ffvideo[stream]->st;
-       return st->codec->coded_width;
+       return ffvideo[stream]->avctx->coded_width;
 }
 
 int FFMPEG::ff_coded_height(int stream)
 {
-       AVStream *st = ffvideo[stream]->st;
-       return st->codec->coded_height;
+       return ffvideo[stream]->avctx->coded_height;
 }
 
 float FFMPEG::ff_aspect_ratio(int stream)
@@ -2385,7 +2437,7 @@ float FFMPEG::ff_aspect_ratio(int stream)
 const char* FFMPEG::ff_video_format(int stream)
 {
        AVStream *st = ffvideo[stream]->st;
-       AVCodecID id = st->codec->codec_id;
+       AVCodecID id = st->codecpar->codec_id;
        const AVCodecDescriptor *desc = avcodec_descriptor_get(id);
        return desc ? desc->name : _("Unknown");
 }
@@ -2411,8 +2463,7 @@ int FFMPEG::ff_cpus()
        return file_base->file->cpus;
 }
 
-int FFVideoStream::create_filter(const char *filter_spec,
-               AVCodecContext *src_ctx, AVCodecContext *sink_ctx)
+int FFVideoStream::create_filter(const char *filter_spec, AVCodecParameters *avpar)
 {
        avfilter_register_all();
        const char *sp = filter_spec;
@@ -2430,11 +2481,12 @@ int FFVideoStream::create_filter(const char *filter_spec,
        AVFilter *buffersink = avfilter_get_by_name("buffersink");
 
        int ret = 0;  char args[BCTEXTLEN];
+       AVPixelFormat pix_fmt = (AVPixelFormat)avpar->format;
        snprintf(args, sizeof(args),
                "video_size=%dx%d:pix_fmt=%d:time_base=%d/%d:pixel_aspect=%d/%d",
-               src_ctx->width, src_ctx->height, src_ctx->pix_fmt,
-               src_ctx->time_base.num, src_ctx->time_base.den,
-               src_ctx->sample_aspect_ratio.num, src_ctx->sample_aspect_ratio.den);
+               avpar->width, avpar->height, (int)pix_fmt,
+               st->time_base.num, st->time_base.den,
+               avpar->sample_aspect_ratio.num, avpar->sample_aspect_ratio.den);
        if( ret >= 0 )
                ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                        args, NULL, filter_graph);
@@ -2443,7 +2495,7 @@ int FFVideoStream::create_filter(const char *filter_spec,
                        NULL, NULL, filter_graph);
        if( ret >= 0 )
                ret = av_opt_set_bin(buffersink_ctx, "pix_fmts",
-                       (uint8_t*)&sink_ctx->pix_fmt, sizeof(sink_ctx->pix_fmt),
+                       (uint8_t*)&pix_fmt, sizeof(pix_fmt),
                        AV_OPT_SEARCH_CHILDREN);
        if( ret < 0 )
                ff_err(ret, "FFVideoStream::create_filter");
@@ -2452,8 +2504,7 @@ int FFVideoStream::create_filter(const char *filter_spec,
        return ret >= 0 ? 0 : -1;
 }
 
-int FFAudioStream::create_filter(const char *filter_spec,
-               AVCodecContext *src_ctx, AVCodecContext *sink_ctx)
+int FFAudioStream::create_filter(const char *filter_spec, AVCodecParameters *avpar)
 {
        avfilter_register_all();
        const char *sp = filter_spec;
@@ -2470,10 +2521,11 @@ int FFAudioStream::create_filter(const char *filter_spec,
        AVFilter *buffersrc = avfilter_get_by_name("abuffer");
        AVFilter *buffersink = avfilter_get_by_name("abuffersink");
        int ret = 0;  char args[BCTEXTLEN];
+       AVSampleFormat sample_fmt = (AVSampleFormat)avpar->format;
        snprintf(args, sizeof(args),
                "time_base=%d/%d:sample_rate=%d:sample_fmt=%s:channel_layout=0x%jx",
-               src_ctx->time_base.num, src_ctx->time_base.den, src_ctx->sample_rate,
-               av_get_sample_fmt_name(src_ctx->sample_fmt), src_ctx->channel_layout);
+               st->time_base.num, st->time_base.den, avpar->sample_rate,
+               av_get_sample_fmt_name(sample_fmt), avpar->channel_layout);
        if( ret >= 0 )
                ret = avfilter_graph_create_filter(&buffersrc_ctx, buffersrc, "in",
                        args, NULL, filter_graph);
@@ -2482,15 +2534,15 @@ int FFAudioStream::create_filter(const char *filter_spec,
                        NULL, NULL, filter_graph);
        if( ret >= 0 )
                ret = av_opt_set_bin(buffersink_ctx, "sample_fmts",
-                       (uint8_t*)&sink_ctx->sample_fmt, sizeof(sink_ctx->sample_fmt),
+                       (uint8_t*)&sample_fmt, sizeof(sample_fmt),
                        AV_OPT_SEARCH_CHILDREN);
        if( ret >= 0 )
                ret = av_opt_set_bin(buffersink_ctx, "channel_layouts",
-                       (uint8_t*)&sink_ctx->channel_layout,
-                       sizeof(sink_ctx->channel_layout), AV_OPT_SEARCH_CHILDREN);
+                       (uint8_t*)&avpar->channel_layout,
+                       sizeof(avpar->channel_layout), AV_OPT_SEARCH_CHILDREN);
        if( ret >= 0 )
                ret = av_opt_set_bin(buffersink_ctx, "sample_rates",
-                       (uint8_t*)&sink_ctx->sample_rate, sizeof(sink_ctx->sample_rate),
+                       (uint8_t*)&sample_rate, sizeof(sample_rate),
                        AV_OPT_SEARCH_CHILDREN);
        if( ret < 0 )
                ff_err(ret, "FFAudioStream::create_filter");
@@ -2531,46 +2583,6 @@ int FFStream::create_filter(const char *filter_spec)
        return ret;
 }
 
-void FFStream::add_bsfilter(const char *bsf, const char *ap)
-{
-       bsfilter.append(new BSFilter(bsf,ap));
-}
-
-int FFStream::bs_filter(AVPacket *pkt)
-{
-       if( !bsfilter.size() ) return 0;
-       av_packet_split_side_data(pkt);
-
-       int ret = 0;
-       for( int i=0; i<bsfilter.size(); ++i ) {
-               AVPacket bspkt = *pkt;
-               ret = av_bitstream_filter_filter(bsfilter[i]->bsfc,
-                        st->codec, bsfilter[i]->args, &bspkt.data, &bspkt.size,
-                        pkt->data, pkt->size, pkt->flags & AV_PKT_FLAG_KEY);
-               if( ret < 0 ) break;
-               int size = bspkt.size;
-               uint8_t *data = bspkt.data;
-               if( !ret && bspkt.data != pkt->data ) {
-                       size = bspkt.size;
-                       data = (uint8_t *)av_malloc(size + FF_INPUT_BUFFER_PADDING_SIZE);
-                       if( !data ) { ret = AVERROR(ENOMEM);  break; }
-                       memcpy(data, bspkt.data, size);
-                       memset(data+size, 0, FF_INPUT_BUFFER_PADDING_SIZE);
-                       ret = 1;
-               }
-               if( ret > 0 ) {
-                       pkt->side_data = 0;  pkt->side_data_elems = 0;
-                       av_packet_unref(pkt);
-                       ret = av_packet_from_data(&bspkt, data, size);
-                       if( ret < 0 ) break;
-               }
-               *pkt = bspkt;
-       }
-       if( ret < 0 )
-               ff_err(ret,"FFStream::bs_filter");
-       return ret;
-}
-
 int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
 {
        AVPacket pkt;
@@ -2586,23 +2598,50 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
        index_state->add_audio_markers(ffaudio.size());
 
        for( int i=0; i<(int)fmt_ctx->nb_streams; ++i ) {
+               int ret = 0;
                AVDictionary *copts = 0;
                av_dict_copy(&copts, opts, 0);
                AVStream *st = fmt_ctx->streams[i];
-               AVCodecID codec_id = st->codec->codec_id;
+               AVCodecID codec_id = st->codecpar->codec_id;
                AVCodec *decoder = avcodec_find_decoder(codec_id);
-               if( avcodec_open2(st->codec, decoder, &copts) < 0 ) {
+               AVCodecContext *avctx = avcodec_alloc_context3(decoder);
+               if( !avctx ) {
+                       eprintf(_("cant allocate codec context\n"));
+                       ret = AVERROR(ENOMEM);
+               }
+               if( ret >= 0 ) {
+                       avcodec_parameters_to_context(avctx, st->codecpar);
+                       ret = avcodec_open2(avctx, decoder, &copts);
+               }
+               av_dict_free(&copts);
+               if( ret < 0 ) {
                        fprintf(stderr,"FFMPEG::scan: ");
                        fprintf(stderr,_("codec open failed\n"));
+                       continue;
+               }
+               AVCodecParameters *avpar = st->codecpar;
+               switch( avpar->codec_type ) {
+               case AVMEDIA_TYPE_VIDEO: {
+                       int vidx = ffvideo.size();
+                       while( --vidx>=0 && ffvideo[vidx]->fidx != i );
+                       if( vidx < 0 ) break;
+                       ffvideo[vidx]->avctx = avctx;
+                       break; }
+               case AVMEDIA_TYPE_AUDIO: {
+                       int aidx = ffaudio.size();
+                       while( --aidx>=0 && ffaudio[aidx]->fidx != i );
+                       if( aidx < 0 ) continue;
+                       ffaudio[aidx]->avctx = avctx;
+                       break; }
+               default: break;
                }
-               av_dict_free(&copts);
        }
 
        decode_activate();
        for( int i=0; i<(int)fmt_ctx->nb_streams; ++i ) {
                AVStream *st = fmt_ctx->streams[i];
-               AVCodecContext *avctx = st->codec;
-               if( avctx->codec_type != AVMEDIA_TYPE_AUDIO ) continue;
+               AVCodecParameters *avpar = st->codecpar;
+               if( avpar->codec_type != AVMEDIA_TYPE_AUDIO ) continue;
                int64_t tstmp = st->start_time;
                if( tstmp == AV_NOPTS_VALUE ) continue;
                int aidx = ffaudio.size();
@@ -2632,10 +2671,10 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                int i = pkt.stream_index;
                if( i < 0 || i >= (int)fmt_ctx->nb_streams ) continue;
                AVStream *st = fmt_ctx->streams[i];
-               AVCodecContext *avctx = st->codec;
                if( pkt.pos > *scan_position ) *scan_position = pkt.pos;
 
-               switch( avctx->codec_type ) {
+               AVCodecParameters *avpar = st->codecpar;
+               switch( avpar->codec_type ) {
                case AVMEDIA_TYPE_VIDEO: {
                        int vidx = ffvideo.size();
                        while( --vidx>=0 && ffvideo[vidx]->fidx != i );
@@ -2651,15 +2690,9 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                                index_state->put_video_mark(vidx, frm, pkt.pos);
                        }
 #if 0
-                       while( pkt.size > 0 ) {
-                               av_frame_unref(frame);
-                               int got_frame = 0;
-                               int ret = vid->decode_frame(&pkt, frame, got_frame);
-                               if( ret <= 0 ) break;
-//                             if( got_frame ) {}
-                               pkt.data += ret;
-                               pkt.size -= ret;
-                       }
+                       ret = avcodec_send_packet(vid->avctx, pkt);
+                       if( ret < 0 ) break;
+                       while( (ret=vid->decode_frame(frame)) > 0 ) {}
 #endif
                        break; }
                case AVMEDIA_TYPE_AUDIO: {
@@ -2676,34 +2709,29 @@ int FFMPEG::scan(IndexState *index_state, int64_t *scan_position, int *canceled)
                                if( sample >= 0 )
                                        index_state->put_audio_mark(aidx, sample, pkt.pos);
                        }
-                       while( pkt.size > 0 ) {
-                               int ch = aud->channel0,  nch = aud->channels;
-                               int64_t pos = index_state->pos(ch);
-                               if( pos != aud->curr_pos ) {
+                       ret = avcodec_send_packet(aud->avctx, &pkt);
+                       if( ret < 0 ) break;
+                       int ch = aud->channel0,  nch = aud->channels;
+                       int64_t pos = index_state->pos(ch);
+                       if( pos != aud->curr_pos ) {
 if( abs(pos-aud->curr_pos) > 1 )
 printf("audio%d pad %jd %jd (%jd)\n", aud->idx, pos, aud->curr_pos, pos-aud->curr_pos);
-                                       index_state->pad_data(ch, nch, aud->curr_pos);
-                               }
-                               av_frame_unref(frame);
-                               int got_frame = 0;
-                               int ret = aud->decode_frame(&pkt, frame, got_frame);
-                               if( ret <= 0 ) break;
-                               if( got_frame && frame->channels == nch ) {
-                                       float *samples;
-                                       int len = aud->get_samples(samples,
-                                                &frame->extended_data[0], frame->nb_samples);
-                                       pos = aud->curr_pos;
-                                       if( (aud->curr_pos += len) >= 0 ) {
-                                               if( pos < 0 ) {
-                                                       samples += -pos * nch;
-                                                       len = aud->curr_pos;
-                                               }
-                                               for( int i=0; i<nch; ++i )
-                                                       index_state->put_data(ch+i,nch,samples+i,len);
+                               index_state->pad_data(ch, nch, aud->curr_pos);
+                       }
+                       while( (ret=aud->decode_frame(frame)) > 0 ) {
+                               if( frame->channels != nch ) break;
+                               float *samples;
+                               int len = aud->get_samples(samples,
+                                        &frame->extended_data[0], frame->nb_samples);
+                               pos = aud->curr_pos;
+                               if( (aud->curr_pos += len) >= 0 ) {
+                                       if( pos < 0 ) {
+                                               samples += -pos * nch;
+                                               len = aud->curr_pos;
                                        }
+                                       for( int i=0; i<nch; ++i )
+                                               index_state->put_data(ch+i,nch,samples+i,len);
                                }
-                               pkt.data += ret;
-                               pkt.size -= ret;
                        }
                        break; }
                default: break;
index f665fa922a5b6afc9e0ce0cabdd168543c7d7431..e70bcbfb266f404beba4ab9491d03a243d5c34f6 100644 (file)
@@ -89,11 +89,10 @@ public:
 
        virtual int is_audio() = 0;
        virtual int is_video() = 0;
-       virtual int decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame) = 0;
-       virtual int encode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame) = 0;
+       virtual int decode_frame(AVFrame *frame) = 0;
+       virtual int encode_frame(AVFrame *frame) = 0;
        virtual int init_frame(AVFrame *frame) = 0;
-       virtual int create_filter(const char *filter_spec,
-               AVCodecContext *src_ctx, AVCodecContext *sink_ctx) = 0;
+       virtual int create_filter(const char *filter_spec, AVCodecParameters *avpar) = 0;
        virtual void load_markers() = 0;
        virtual IndexMarks *get_markers() = 0;
        int create_filter(const char *filter_spec);
@@ -104,28 +103,13 @@ public:
        FFMPEG *ffmpeg;
        AVStream *st;
        AVFormatContext *fmt_ctx;
+       AVCodecContext *avctx;
 
        AVFilterContext *buffersink_ctx;
        AVFilterContext *buffersrc_ctx;
        AVFilterGraph *filter_graph;
        AVFrame *frame, *fframe;
-
-       class BSFilter {
-       public:
-               AVBitStreamFilterContext *bsfc;
-               const char *args;
-               BSFilter(const char *bsf, const char *ap) {
-                       bsfc = av_bitstream_filter_init(bsf);
-                       args = ap ? cstrdup(ap) : 0;
-               }
-               ~BSFilter() {
-                       av_bitstream_filter_close(bsfc);
-                       delete [] args;
-               }
-       };
-       void add_bsfilter(const char *bsf, const char *ap);
-       ArrayList<BSFilter *> bsfilter;
-       int bs_filter(AVPacket *pkt);
+       AVBSFContext *bsfc;
 
        FFPacket ipkt;
        int need_packet, flushed;
@@ -168,15 +152,13 @@ public:
        int is_video() { return 0; }
        int get_samples(float *&samples, uint8_t **data, int len);
        int load_history(uint8_t **data, int len);
-       int decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame);
-       int encode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame);
-       int create_filter(const char *filter_spec,
-               AVCodecContext *src_ctx, AVCodecContext *sink_ctx);
+       int decode_frame(AVFrame *frame);
+       int encode_frame(AVFrame *frame);
+       int create_filter(const char *filter_spec, AVCodecParameters *avpar);
        void load_markers();
        IndexMarks *get_markers();
 
        int encode_activate();
-       int nb_samples();
        int64_t load_buffer(double ** const sp, int len);
        int in_history(int64_t pos);
        void reset_history();
@@ -225,10 +207,9 @@ public:
        virtual ~FFVideoStream();
        int is_audio() { return 0; }
        int is_video() { return 1; }
-       int decode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame);
-       int encode_frame(AVPacket *pkt, AVFrame *frame, int &got_frame);
-       int create_filter(const char *filter_spec,
-               AVCodecContext *src_ctx, AVCodecContext *sink_ctx);
+       int decode_frame(AVFrame *frame);
+       int encode_frame(AVFrame *frame);
+       int create_filter(const char *filter_spec, AVCodecParameters *avpar);
        void load_markers();
        IndexMarks *get_markers();
 
@@ -267,10 +248,8 @@ public:
                 char *codec, char *codec_options, int len);
        static void set_asset_format(Asset *asset, const char *text);
        int get_file_format();
-       int get_encoder(const char *options,
-               char *format, char *codec, char *bsfilter, char *bsargs);
-       int get_encoder(FILE *fp,
-               char *format, char *codec, char *bsfilter, char *bsargs);
+       int get_encoder(const char *options, char *format, char *codec, char *bsfilter);
+       int get_encoder(FILE *fp, char *format, char *codec, char *bsfilter);
        int read_options(const char *options, AVDictionary *&opts, int skip=0);
        int scan_options(const char *options, AVDictionary *&opts, AVStream *st);
        int read_options(FILE *fp, const char *options, AVDictionary *&opts);
index 1fa0dfc19973a3b8232378e3e9986d9927dc0112..cc3cafae40ddf2418049274c4550ee451c6bb7ea 100644 (file)
@@ -72,8 +72,6 @@ int FileAC3::reset_parameters_derived()
        temp_raw = 0;
        temp_raw_size = 0;
        temp_raw_allocated = 0;
-       temp_compressed = 0;
-       compressed_allocated = 0;
        return 0;
 }
 
@@ -130,7 +128,7 @@ int FileAC3::open_file(int rd, int wr)
 
        if( !result && wr )
        {
-               //avcodec_init();
+               //avcodec_init();
                avcodec_register_all();
                codec = avcodec_find_encoder(AV_CODEC_ID_AC3);
                if(!codec)
@@ -148,6 +146,7 @@ int FileAC3::open_file(int rd, int wr)
                        int sample_rate = asset->sample_rate;
                        int64_t layout = get_channel_layout(channels);
                        int bitrate = asset->ac3_bitrate * 1000;
+                       av_init_packet(&avpkt);
                        codec_context = avcodec_alloc_context3(codec);
                        codec_context->bit_rate = bitrate;
                        codec_context->sample_rate = sample_rate;
@@ -179,6 +178,7 @@ int FileAC3::close_file()
        }
        if(codec_context)
        {
+               encode_flush();
                avcodec_close(codec_context);
                avcodec_free_context(&codec_context);
                codec = 0;
@@ -195,11 +195,6 @@ int FileAC3::close_file()
                delete [] temp_raw;
                temp_raw = 0;
        }
-       if(temp_compressed)
-       {
-               delete [] temp_compressed;
-               temp_compressed = 0;
-       }
        reset_parameters();
        FileBase::close_file();
        return 0;
@@ -229,6 +224,57 @@ int FileAC3::get_index(IndexFile *index_file, MainProgressBar *progress_bar)
 //     { }
 // };
 
+int FileAC3::write_packet()
+{
+       AVCodecContext *&avctx = codec_context;
+       int ret = avcodec_receive_packet(avctx, &avpkt);
+       if( ret >= 0 ) {
+               ret = 0;
+               if( avpkt.data && avpkt.size > 0 ) {
+                       int sz = fwrite(avpkt.data, 1, avpkt.size, fd);
+                       if( sz == avpkt.size ) ret = 1;
+               }
+               if( !ret )
+                       eprintf(_("Error while writing samples. \n%m\n"));
+               av_packet_unref(&avpkt);
+       }
+       else if( ret == AVERROR_EOF )
+               ret = 0;
+       return ret;
+}
+
+int FileAC3::encode_frame(AVFrame *frame)
+{
+       AVCodecContext *&avctx = codec_context;
+       int ret = 0, pkts = 0;
+       for( int retry=100; --retry>=0; ) {
+               ret = avcodec_send_frame(avctx, frame);
+               if( ret >= 0 ) return pkts;
+               if( ret != AVERROR(EAGAIN) ) break;
+               if( (ret=write_packet()) < 0 ) break;
+               if( !ret ) return pkts;
+               ++pkts;
+       }
+       if( ret < 0 ) {
+               char errmsg[BCTEXTLEN];
+               av_strerror(ret, errmsg, sizeof(errmsg));
+               fprintf(stderr, "FileAC3::encode_frame: encode failed: %s\n", errmsg);
+       }
+       return ret;
+}
+
+int FileAC3::encode_flush()
+{
+       AVCodecContext *&avctx = codec_context;
+       int ret = avcodec_send_frame(avctx, 0);
+       while( (ret=write_packet()) > 0 );
+       if( ret < 0 ) {
+               char errmsg[BCTEXTLEN];
+               av_strerror(ret, errmsg, sizeof(errmsg));
+               fprintf(stderr, "FileAC3::encode_flush: encode failed: %s\n", errmsg);
+       }
+       return ret;
+}
 
 int FileAC3::write_samples(double **buffer, int64_t len)
 {
@@ -248,14 +294,6 @@ int FileAC3::write_samples(double **buffer, int64_t len)
                temp_raw_allocated = new_allocated;
        }
 
-// Allocate compressed data buffer
-       if(temp_raw_allocated * asset->channels * 2 > compressed_allocated)
-       {
-               compressed_allocated = temp_raw_allocated * asset->channels * 2;
-               delete [] temp_compressed;
-               temp_compressed = new unsigned char[compressed_allocated];
-       }
-
 // Append buffer to temp raw
        int16_t *out_ptr = temp_raw + temp_raw_size * asset->channels;
        for(int i = 0; i < len; i++)
@@ -271,15 +309,11 @@ int FileAC3::write_samples(double **buffer, int64_t len)
 
        AVCodecContext *&avctx = codec_context;
        int frame_size = avctx->frame_size;
-       int output_size = 0, cur_sample = 0, ret = 0;
-       for(cur_sample = 0; !ret &&
+       int cur_sample = 0, ret = 0;
+       for(cur_sample = 0; ret >= 0 &&
                cur_sample + frame_size <= temp_raw_size;
                cur_sample += frame_size)
        {
-               AVPacket avpkt;
-               av_init_packet(&avpkt);
-               avpkt.data = temp_compressed + output_size;
-               avpkt.size = compressed_allocated - output_size;
                AVFrame *frame = av_frame_alloc();
                frame->nb_samples = frame_size;
                frame->format = avctx->sample_fmt;
@@ -296,18 +330,8 @@ int FileAC3::write_samples(double **buffer, int64_t len)
                if( ret >= 0 ) {
                        frame->pts = avctx->sample_rate && avctx->time_base.num ?
                                file->get_audio_position() : AV_NOPTS_VALUE ;
-                       int got_packet = 0;
-                       ret = avcodec_encode_audio2(avctx, &avpkt, frame, &got_packet);
-                       if( ret < 0 ) {
-                               char errmsg[BCSTRLEN];
-                               av_strerror(ret, errmsg, sizeof(errmsg));
-                               fprintf(stderr, "avcodec_encode_audio2 failed. \n%s\n", errmsg);
-                       }
+                       ret = encode_frame(frame);
                }
-               av_packet_free_side_data(&avpkt);
-               output_size += avpkt.size;
-               if(frame->extended_data != frame->data)
-                       av_freep(&frame->extended_data);
                av_frame_free(&frame);
        }
 
@@ -317,12 +341,6 @@ int FileAC3::write_samples(double **buffer, int64_t len)
                (temp_raw_size - cur_sample) * sizeof(int16_t) * asset->channels);
        temp_raw_size -= cur_sample;
 
-       int bytes_written = fwrite(temp_compressed, 1, output_size, fd);
-       if(bytes_written < output_size)
-       {
-               eprintf(_("Error while writing samples. \n%m\n"));
-               return 1;
-       }
        return 0;
 }
 
index c2a30b287f5cd2aea441fc41f1a069d5376f0ed4..9304a80f4303f6c5bf2e360b0031b1fd595ff1df 100644 (file)
@@ -55,8 +55,12 @@ public:
        int read_samples(double *buffer, int64_t len);
        int write_samples(double **buffer, int64_t len);
        int get_index(IndexFile *index_file, MainProgressBar *progress_bar);
+       int write_packet();
+       int encode_frame(AVFrame *frame);
+       int encode_flush();
 
 private:
+       AVPacket avpkt;
        AVCodec *codec;
        AVCodecContext *codec_context;
        SwrContext *resample_context;
@@ -66,8 +70,6 @@ private:
        int16_t *temp_raw;
        int temp_raw_allocated;
        int temp_raw_size;
-       unsigned char *temp_compressed;
-       int compressed_allocated;
 };
 
 
index 5c9b9bd3463cb0da38521906a08460ce45ac231a..8ddf44f17c67195c7fa4c4091b869a61b5d6f567 100644 (file)
@@ -792,7 +792,8 @@ int FileMPEG::create_toc(char *toc_path)
 // delete any existing toc files
        char toc_file[BCTEXTLEN];
        strcpy(toc_file, toc_path);
-       remove(toc_file);
+       if( strcmp(toc_file, asset->path) )
+               remove(toc_file);
        char *bp = strrchr(toc_file, '/');
        if( !bp ) bp = toc_file;
        char *sfx = strrchr(bp,'.');
index f93a4ba96c72d488e2355378e1a2eb90db8eff13..f69ab3e847898b9e5520b194df0174b0fb0b529c 100644 (file)
@@ -719,7 +719,7 @@ int Preferences::get_asset_file_path(Asset *asset, char *path)
 {
        strcpy(path, asset->path);
        int result = !access(path, R_OK) ? 0 : -1;
-       if( !result && ( asset->format == FILE_MPEG ||
+       if( !result && ( asset->format == FILE_MPEG || asset->format == FILE_AC3 ||
                asset->format == FILE_VMPEG || asset->format == FILE_AMPEG ) ) {
                char source_filename[BCTEXTLEN], index_filename[BCTEXTLEN];
                IndexFile::get_index_filename(source_filename,
index c0322c3949e679bc041b263a52bd87bf84de7112..369b199c27aad70fc46d76179132cc4f3f1d966c 100644 (file)
@@ -113,6 +113,11 @@ gtk_window::gtk_window(int width, int height)
 
 gtk_window::~gtk_window()
 {
+  gtk_widget_destroy(window);
+  g_object_unref(pbuf0);
+  g_object_unref(img0);
+  g_object_unref(pbuf1);
+  g_object_unref(img1);
   delete [] row0;
   delete [] row1;
   pthread_mutex_destroy(&draw);
@@ -178,6 +183,7 @@ public:
   AVPixelFormat pix_fmt;
   double frame_rate;
   int width, height;
+  int need_packet, eof;
   int open_decoder(const char *filename, int vid_no);
   void close_decoder();
   AVFrame *read_frame();
@@ -191,6 +197,8 @@ ffcmpr::ffcmpr()
   this->st = 0;
   this->ctx = 0 ;
   this->frame_rate = 0;
+  this->need_packet = 0;
+  this->eof = 0;
   this->pix_fmt = AV_PIX_FMT_NONE;
   width = height = 0;
 }
@@ -199,6 +207,7 @@ void ffcmpr::close_decoder()
 {
   av_packet_unref(&ipkt);
   if( !fmt_ctx ) return;
+  if( ctx ) avcodec_free_context(&ctx);
   avformat_close_input(&fmt_ctx);
   av_frame_free(&ipic);
 }
@@ -235,28 +244,31 @@ int ffcmpr::open_decoder(const char *filename, int vid_no)
   this->st = 0;
   for( int i=0; !this->st && ret>=0 && i<(int)fmt_ctx->nb_streams; ++i ) {
     AVStream *fst = fmt_ctx->streams[i];
-    AVMediaType type = fst->codec->codec_type;
+    AVMediaType type = fst->codecpar->codec_type;
     if( type != AVMEDIA_TYPE_VIDEO ) continue;
     if( --vid_no < 0 ) this->st = fst;
   }
 
-  AVCodecID codec_id = st->codec->codec_id;
+  AVCodecID codec_id = st->codecpar->codec_id;
   AVDictionary *copts = 0;
   //av_dict_copy(&copts, opts, 0);
   AVCodec *decoder = avcodec_find_decoder(codec_id);
-  if( avcodec_open2(st->codec, decoder, &copts) < 0 ) {
+  ctx = avcodec_alloc_context3(decoder);
+  avcodec_parameters_to_context(ctx, st->codecpar);
+  if( avcodec_open2(ctx, decoder, &copts) < 0 ) {
     fprintf(stderr,"codec open failed: %s\n", filename);
     return -1;
   }
   av_dict_free(&copts);
   ipic = av_frame_alloc();
+  eof = 0;
+  need_packet = 1;
 
   AVRational framerate = av_guess_frame_rate(fmt_ctx, st, 0);
   this->frame_rate = !framerate.den ? 0 : (double)framerate.num / framerate.den;
-  this->ctx = st->codec;
-  this->pix_fmt = ctx->pix_fmt;
-  this->width  = ctx->width;
-  this->height = ctx->height;
+  this->pix_fmt = (AVPixelFormat)st->codecpar->format;
+  this->width  = st->codecpar->width;
+  this->height = st->codecpar->height;
   return 0;
 }
 
@@ -265,21 +277,29 @@ AVFrame *ffcmpr::read_frame()
   av_frame_unref(ipic);
 
   for( int retrys=1000; --retrys>=0; ) {
-    av_packet_unref(&ipkt);
-    int ret = av_read_frame(fmt_ctx, &ipkt);
-    if( ret == AVERROR_EOF ) break;
-    if( ret != 0 ) continue;
-    if( !ipkt.data ) continue;
-    if( ipkt.stream_index != st->index ) continue;
-    while( ipkt.size > 0 ) {
-      int got_frame = 0;
-      ret = avcodec_decode_video2(st->codec, ipic, &got_frame, &ipkt);
-      if( ret <= 0 ) break;
-      if( got_frame )
-        return ipic;
-      ipkt.data += ret;
-      ipkt.size -= ret;
+    if( need_packet ) {
+      if( eof ) return 0;
+      AVPacket *pkt = &ipkt;
+      av_packet_unref(pkt);
+      int ret = av_read_frame(fmt_ctx, pkt);
+      if( ret < 0 ) {
+        if( ret != AVERROR_EOF ) return 0;
+        ret = 0;  eof = 1;  pkt = 0;
+      }
+      if( pkt ) {
+        if( pkt->stream_index != st->index ) continue;
+        if( !pkt->data || !pkt->size ) continue;
+      }
+      avcodec_send_packet(ctx, pkt);
+      need_packet = 0;
     }
+    int ret = avcodec_receive_frame(ctx, ipic);
+    if( ret >= 0 ) return ipic;
+    if( ret != AVERROR(EAGAIN) ) {
+      eof = 1; need_packet = 0;
+      break;
+    }
+    need_packet = 1;
   }
   return 0;
 }
@@ -388,7 +408,9 @@ int main(int ac, char **av)
     gw.post();
   }
 
+  av_freep(&afrm->data);
   av_frame_free(&afrm);
+  av_freep(&bfrm->data);
   av_frame_free(&bfrm);
   
   b.close_decoder();
index 99975baea917810f70d88683ce756bf88a1e2ca4..da5aadec94318d8275513c2902f7714e361be8fb 100644 (file)
@@ -119,17 +119,6 @@ PKG_3RD([esound],[no],
     .libs/libesddsp.a ],
   [ . ])
 
-PKG_3RD([faac],[auto],
-  [faac-1.28],
-  [ libfaac/.libs/libfaac.a ],
-  [ include ])
-
-PKG_3RD([faad2],[auto],
-  [faad2-2.7],
-  [ libfaad/.libs/libfaad.a \
-    common/mp4ff/libmp4ff.a ],
-  [ include ])
-
 PKG_3RD([fdk],[auto],
   [fdk-aac-0.1.5],
   [ .libs/libfdk-aac.a ],
@@ -452,10 +441,6 @@ CHECK_LIB([a52dec], [a52], [a52_init])
 CHECK_HEADERS([a52dec], [a52 headers], [a52.h])
 CHECK_LIB([encore], [encore], [encore])
 CHECK_HEADERS([encore], [encore headers], [encore.h])
-CHECK_LIB([faac], [faac], [faacEncOpen])
-CHECK_HEADERS([faac], [faac headers], [faac.h])
-CHECK_LIB([faad2], [faad], [faacDecInit])
-CHECK_HEADERS([faad2], [faad headers], [faad.h])
 CHECK_LIB([giflib], [gif], [DGifOpen])
 CHECK_HEADERS([giflib], [gif lib headers], [gif_lib.h])
 CHECK_LIB([fdk], [fdk-aac], [faacDecInit])
@@ -596,7 +581,7 @@ AC_DEFUN([PKG_FORCED],[PKG_STATIC([$1],[forced])])
 
 # order matters
 for dep in \
-        ffmpeg/faac ffmpeg/faad2 ffmpeg/twolame ffmpeg/lame ffmpeg/openjpeg \
+        ffmpeg/twolame ffmpeg/lame ffmpeg/openjpeg \
         ffmpeg/libvorbis ffmpeg/libtheora ffmpeg/x264 ffmpeg/x265 ffmpeg/fdk \
         libiec61883/libraw1394 libavc1394/librom1394 \
         openexr/ilmbase ilmbase/libogg \
@@ -629,8 +614,6 @@ PKG_PROVIDE([djbfft])
 PKG_PROVIDE([encore])
 PKG_PROVIDE([audiofile],[$WANT_ESOUND])
 PKG_PROVIDE([esound],[$WANT_ESOUND])
-PKG_PROVIDE([faac])
-PKG_PROVIDE([faad2])
 PKG_PROVIDE([fdk])
 PKG_PROVIDE([ffmpeg])
 PKG_PROVIDE([fftw])
index 7bf3dc705c48e0aa45c72d6b4400cdb1f9d4f862..8b8eafd1146561429e5a2caac9f081ac6aea937e 100644 (file)
@@ -1,3 +1,3 @@
-mov libfdk_aac | aac_adtstoasc
+mov libfdk_aac
 strict -2
 b 256000
index 6d957f365f93bf266a13554cef541690e684f4eb..adcf1d7fd43b03a8f2f7de4dc4c1eeb60aa77fda 100644 (file)
@@ -1,2 +1,2 @@
-mp4 libfdk_aac | aac_adtstoasc
+mp4 libfdk_aac
 strict -2
index 5e6f63e1ad7da91ecff8c75bbb2f5a398d5d5b4b..207c7b64c6e66e8ee4859bce5545c6e9545cf2a9 100644 (file)
@@ -1 +1 @@
-mov libfdk_aac | aac_adtstoasc
+mov libfdk_aac
index 0fda17160901130f7df35e37b0372ac999a7d089..57fa1beb106f23b8f9b34a878ce068b235bc64de 100644 (file)
@@ -1,3 +1,4 @@
+dvd
 packetsize 2048
 muxrate 10080000
 preload 500000
index 2310a19fb62c409fdab4e451f0bef2ae686e5044..8b164db931ca20f3771eb52d93890641d5f36db9 100644 (file)
@@ -1,10 +1,14 @@
 #include "../libzmpeg3.h"
 
+#ifndef MM_ACCEL_DJBFFT
+#define MM_ACCEL_DJBFFT 0x00000001
+#endif
+
 zaudio_decoder_ac3_t::
 audio_decoder_ac3_t()
 {
   stream = new bits_t(0, 0);
-  state = a52_init(0);
+  state = a52_init(MM_ACCEL_DJBFFT);
   output = a52_samples(state);
 }
 
diff --git a/cinelerra-5.1/thirdparty/src/a52dec.patch1 b/cinelerra-5.1/thirdparty/src/a52dec.patch1
new file mode 100644 (file)
index 0000000..bb5f698
--- /dev/null
@@ -0,0 +1,19 @@
+diff -urN a/liba52/imdct.c b/liba52/imdct.c
+--- a/liba52/imdct.c   2002-07-27 19:52:07.000000000 -0600
++++ b/liba52/imdct.c   2017-04-19 17:25:19.609452493 -0600
+@@ -419,13 +419,13 @@
+ #ifdef LIBA52_DJBFFT
+     if (mm_accel & MM_ACCEL_DJBFFT) {
+-      fprintf (stderr, "Using djbfft for IMDCT transform\n");
++/*    fprintf (stderr, "Using djbfft for IMDCT transform\n"); */
+       ifft128 = (void (*) (complex_t *)) fftc4_un128;
+       ifft64 = (void (*) (complex_t *)) fftc4_un64;
+     } else
+ #endif
+     {
+-      fprintf (stderr, "No accelerated IMDCT transform found\n");
++/*    fprintf (stderr, "No accelerated IMDCT transform found\n"); */
+       ifft128 = ifft128_c;
+       ifft64 = ifft64_c;
+     }
diff --git a/cinelerra-5.1/thirdparty/src/faac-1.28.tar.xz b/cinelerra-5.1/thirdparty/src/faac-1.28.tar.xz
deleted file mode 100644 (file)
index a8328ef..0000000
Binary files a/cinelerra-5.1/thirdparty/src/faac-1.28.tar.xz and /dev/null differ
diff --git a/cinelerra-5.1/thirdparty/src/faac.patch1 b/cinelerra-5.1/thirdparty/src/faac.patch1
deleted file mode 100644 (file)
index be4aa9a..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
---- faac-1.28/common/mp4v2/mpeg4ip.h.orig      2015-04-16 07:51:47.134014449 -0600
-+++ faac-1.28/common/mp4v2/mpeg4ip.h   2015-04-16 07:52:37.955396415 -0600
-@@ -120,6 +120,7 @@
- #endif
- #include <sys/param.h>
-+#if 0
- #ifdef __cplusplus
- extern "C" {
- #endif
-@@ -127,6 +128,7 @@
- #ifdef __cplusplus
- }
- #endif
-+#endif
- #define OPEN_RDWR O_RDWR
- #define OPEN_CREAT O_CREAT 
diff --git a/cinelerra-5.1/thirdparty/src/faac.patch2 b/cinelerra-5.1/thirdparty/src/faac.patch2
deleted file mode 100644 (file)
index 5b8ec76..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
---- faac-1.28.orig/configure.in        2009-02-04 17:55:38.000000000 -0700
-+++ faac-1.28/configure.in     2016-07-05 09:30:08.119772898 -0600
-@@ -34,9 +34,9 @@
-                             external_mp4v2=no, -lstdc++),
-                external_mp4v2=no, [#include <mp4.h>])
--if test x$external_mp4v2 = xyes; then
--  AC_MSG_NOTICE([*** Building with external mp4v2 ***])
--else
-+# if test x$external_mp4v2 = xyes; then
-+#  AC_MSG_NOTICE([*** Building with external mp4v2 ***])
-+# else
-   if test x$WITHMP4V2 = xyes; then
-      AC_MSG_NOTICE([*** Building with internal mp4v2 ***])
-      AM_CONDITIONAL(WITH_MP4V2, true)
-@@ -44,7 +44,7 @@
-      MY_DEFINE(HAVE_LIBMP4V2)
-   else
-      AC_MSG_NOTICE([*** Building WITHOUT mp4v2 ***])
--  fi
-+#  fi
- fi
- dnl Check for DRM mode
diff --git a/cinelerra-5.1/thirdparty/src/faad2-2.7.tar.xz b/cinelerra-5.1/thirdparty/src/faad2-2.7.tar.xz
deleted file mode 100644 (file)
index d27781c..0000000
Binary files a/cinelerra-5.1/thirdparty/src/faad2-2.7.tar.xz and /dev/null differ
diff --git a/cinelerra-5.1/thirdparty/src/ffmpeg.patch3 b/cinelerra-5.1/thirdparty/src/ffmpeg.patch3
deleted file mode 100644 (file)
index 0644623..0000000
+++ /dev/null
@@ -1,87 +0,0 @@
-diff -urN a/libavcodec/avcodec.h b/libavcodec/avcodec.h
---- a/libavcodec/avcodec.h     2017-04-12 19:55:55.000000000 -0600
-+++ b/libavcodec/avcodec.h     2017-04-16 16:16:04.497012383 -0600
-@@ -4600,7 +4600,7 @@
- attribute_deprecated
- int av_packet_merge_side_data(AVPacket *pkt);
--attribute_deprecated
-+//attribute_deprecated
- int av_packet_split_side_data(AVPacket *pkt);
- #endif
-@@ -4838,7 +4838,7 @@
-  *
- * @deprecated Use avcodec_send_packet() and avcodec_receive_frame().
-  */
--attribute_deprecated
-+//attribute_deprecated
- int avcodec_decode_audio4(AVCodecContext *avctx, AVFrame *frame,
-                           int *got_frame_ptr, const AVPacket *avpkt);
-@@ -4887,7 +4887,7 @@
-  *
-  * @deprecated Use avcodec_send_packet() and avcodec_receive_frame().
-  */
--attribute_deprecated
-+//attribute_deprecated
- int avcodec_decode_video2(AVCodecContext *avctx, AVFrame *picture,
-                          int *got_picture_ptr,
-                          const AVPacket *avpkt);
-@@ -5363,7 +5363,7 @@
-  *
-  * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead
-  */
--attribute_deprecated
-+//attribute_deprecated
- int avcodec_encode_audio2(AVCodecContext *avctx, AVPacket *avpkt,
-                           const AVFrame *frame, int *got_packet_ptr);
-@@ -5402,7 +5402,7 @@
-  *
-  * @deprecated use avcodec_send_frame()/avcodec_receive_packet() instead
-  */
--attribute_deprecated
-+//attribute_deprecated
- int avcodec_encode_video2(AVCodecContext *avctx, AVPacket *avpkt,
-                           const AVFrame *frame, int *got_packet_ptr);
-@@ -5924,7 +5924,7 @@
-  * @return a bitstream filter context if a matching filter was found
-  * and successfully initialized, NULL otherwise
-  */
--attribute_deprecated
-+//attribute_deprecated
- AVBitStreamFilterContext *av_bitstream_filter_init(const char *name);
- /**
-@@ -5956,7 +5956,7 @@
-  * its starting address). A special case is if *poutbuf was set to NULL and
-  * *poutbuf_size was set to 0, which indicates the packet should be dropped.
-  */
--attribute_deprecated
-+//attribute_deprecated
- int av_bitstream_filter_filter(AVBitStreamFilterContext *bsfc,
-                                AVCodecContext *avctx, const char *args,
-                                uint8_t **poutbuf, int *poutbuf_size,
-@@ -5968,7 +5968,7 @@
-  * @param bsf the bitstream filter context created with
-  * av_bitstream_filter_init(), can be NULL
-  */
--attribute_deprecated
-+//attribute_deprecated
- void av_bitstream_filter_close(AVBitStreamFilterContext *bsf);
- /**
-diff -urN a/libavformat/avformat.h b/libavformat/avformat.h
---- a/libavformat/avformat.h   2017-04-12 19:55:55.000000000 -0600
-+++ b/libavformat/avformat.h   2017-04-16 16:16:04.499012276 -0600
-@@ -889,7 +889,7 @@
-     /**
-      * @deprecated use the codecpar struct instead
-      */
--    attribute_deprecated
-+//    attribute_deprecated
-     AVCodecContext *codec;
- #endif
-     void *priv_data;