[med-svn] r9056 - trunk/packages/vxl/trunk/debian/patches

Mathieu Malaterre malat-guest at alioth.debian.org
Tue Dec 20 10:10:36 UTC 2011


Author: malat-guest
Date: 2011-12-20 10:10:35 +0000 (Tue, 20 Dec 2011)
New Revision: 9056

Added:
   trunk/packages/vxl/trunk/debian/patches/libav_trunk.patch
Modified:
   trunk/packages/vxl/trunk/debian/patches/series
Log:
redo patch for ffmpeg

Added: trunk/packages/vxl/trunk/debian/patches/libav_trunk.patch
===================================================================
--- trunk/packages/vxl/trunk/debian/patches/libav_trunk.patch	                        (rev 0)
+++ trunk/packages/vxl/trunk/debian/patches/libav_trunk.patch	2011-12-20 10:10:35 UTC (rev 9056)
@@ -0,0 +1,1167 @@
+http://vxl.svn.sf.net/viewvc/vxl?view=revision&revision=33908
+
+Index: vxl-1.14.0/core/vidl/vidl_ffmpeg_ostream_v4.txx
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ vxl-1.14.0/core/vidl/vidl_ffmpeg_ostream_v4.txx	2011-12-20 11:07:57.000000000 +0100
+@@ -0,0 +1,540 @@
++// This is core/vidl/vidl_ffmpeg_ostream_v4.txx
++#ifndef vidl_ffmpeg_ostream_v3_txx_
++#define vidl_ffmpeg_ostream_v3_txx_
++#include "vidl_ffmpeg_ostream.h"
++//:
++// \file
++// \author Matt Leotta
++// \author Amitha Perera
++// \author David Law
++// \date   26 Jan 2009
++//
++// Update implementation based on
++// ffmpeg git hash 139f3ac42dcf24eb8c59af4aaab4e9afdccbc996
++//
++//-----------------------------------------------------------------------------
++
++#include "vidl_ffmpeg_init.h"
++#include "vidl_ffmpeg_convert.h"
++#include "vidl_frame.h"
++#include "vidl_convert.h"
++#include <vcl_cstring.h>
++#include <vcl_climits.h>
++#include <vil/vil_memory_chunk.h>
++
++extern "C" {
++#if FFMPEG_IN_SEVERAL_DIRECTORIES
++#include <libavformat/avformat.h>
++#else
++#include <ffmpeg/avformat.h>
++#endif
++}
++
++//-----------------------------------------------------------------------------
++
++
++struct vidl_ffmpeg_ostream::pimpl
++{
++  pimpl()
++  : fmt_cxt_( 0 ),
++  file_opened_( false ),
++  codec_opened_( false ),
++  cur_frame_( 0 ),
++  video_rc_eq_(NULL)
++  { }
++
++  AVFormatContext* fmt_cxt_;
++  bool file_opened_;
++  bool codec_opened_;
++  vil_memory_chunk_sptr bit_buf_;
++  unsigned int cur_frame_;
++  char* video_rc_eq_;
++};
++
++
++//-----------------------------------------------------------------------------
++
++
++//: Constructor
++vidl_ffmpeg_ostream::
++vidl_ffmpeg_ostream()
++  : os_( new vidl_ffmpeg_ostream::pimpl )
++{
++  vidl_ffmpeg_init();
++}
++
++
++//: Destructor
++vidl_ffmpeg_ostream::
++~vidl_ffmpeg_ostream()
++{
++  close();
++  delete os_;
++}
++
++
++//: Constructor - opens a stream
++vidl_ffmpeg_ostream::
++vidl_ffmpeg_ostream(const vcl_string& filename,
++                    const vidl_ffmpeg_ostream_params& params)
++  : os_( new vidl_ffmpeg_ostream::pimpl ),
++    filename_(filename), params_(params)
++{
++  vidl_ffmpeg_init();
++}
++
++
++//: Open the stream
++bool
++vidl_ffmpeg_ostream::
++open()
++{
++  // Close any open files
++  close();
++
++  // a raw video packet is the same size as the input image. Others
++  // are smaller.
++  os_->bit_buf_ = new vil_memory_chunk( params_.ni_ * params_.nj_ * 3, VIL_PIXEL_FORMAT_BYTE );
++
++  os_->fmt_cxt_ = avformat_alloc_context();
++
++  AVOutputFormat* file_oformat = 0;
++  if ( params_.file_format_ == vidl_ffmpeg_ostream_params::GUESS ) {
++    file_oformat = av_guess_format(NULL, filename_.c_str(), NULL);
++    if (!file_oformat) {
++      vcl_cerr << "ffmpeg: Unable for find a suitable output format for "
++               << filename_ << '\n';
++      close();
++      return false;
++    }
++  }
++  else {
++    close();
++    return false;
++  }
++
++  os_->fmt_cxt_->oformat = file_oformat;
++  os_->fmt_cxt_->nb_streams = 0;
++
++  // Create stream
++  AVStream* st = av_new_stream( os_->fmt_cxt_, 0 );
++  if ( !st ) {
++    vcl_cerr << "ffmpeg: could not alloc stream\n";
++    close();
++    return false;
++  }
++
++  //os_->fmt_cxt_->nb_streams = 1;
++
++  AVCodecContext *video_enc = st->codec;
++
++  if (vcl_strcmp(file_oformat->name, "mp4") != 0 ||
++      vcl_strcmp(file_oformat->name, "mov") != 0 ||
++      vcl_strcmp(file_oformat->name, "3gp") != 0 )
++    video_enc->flags |= CODEC_FLAG_GLOBAL_HEADER;
++
++  video_enc->codec_type = AVMEDIA_TYPE_VIDEO;
++
++  switch ( params_.encoder_ )
++  {
++   case vidl_ffmpeg_ostream_params::DEFAULT:
++    video_enc->codec_id = file_oformat->video_codec;
++    break;
++   case vidl_ffmpeg_ostream_params::MPEG4:
++    video_enc->codec_id = CODEC_ID_MPEG4;
++    break;
++   case vidl_ffmpeg_ostream_params::MPEG2VIDEO:
++    video_enc->codec_id = CODEC_ID_MPEG2VIDEO;
++    break;
++   case vidl_ffmpeg_ostream_params::MSMPEG4V2:
++    video_enc->codec_id = CODEC_ID_MSMPEG4V2;
++    break;
++   case vidl_ffmpeg_ostream_params::RAWVIDEO:
++    video_enc->codec_id = CODEC_ID_RAWVIDEO;
++    break;
++   case vidl_ffmpeg_ostream_params::LJPEG:
++    video_enc->codec_id = CODEC_ID_LJPEG;
++    break;
++   case vidl_ffmpeg_ostream_params::HUFFYUV:
++    video_enc->codec_id = CODEC_ID_HUFFYUV;
++    break;
++   case vidl_ffmpeg_ostream_params::DVVIDEO:
++    video_enc->codec_id = CODEC_ID_DVVIDEO;
++    break;
++   default:
++    vcl_cout << "ffmpeg: Unknown encoder type\n";
++    return false;
++  }
++
++  AVCodec* codec = avcodec_find_encoder( video_enc->codec_id );
++  if ( !codec )
++  {
++    vcl_cerr << "ffmpeg_writer:: couldn't find encoder for " << video_enc->codec_id << '\n';
++    return false;
++  }
++
++  video_enc->bit_rate = params_.bit_rate_ * 1000;
++  video_enc->bit_rate_tolerance = params_.video_bit_rate_tolerance_;
++  video_enc->time_base.num = 1000;
++  video_enc->time_base.den = int(params_.frame_rate_*1000);
++
++  if ( codec && codec->supported_framerates )
++  {
++    AVRational const* p = codec->supported_framerates;
++    AVRational req = { video_enc->time_base.den, video_enc->time_base.num };
++    AVRational const* best = NULL;
++    AVRational best_error = { INT_MAX, 1 };
++    for (; p->den!=0; p++)
++    {
++      AVRational error = av_sub_q(req, *p);
++      if ( error.num < 0 )   error.num *= -1;
++      if ( av_cmp_q( error, best_error ) < 0 )
++      {
++        best_error= error;
++        best= p;
++      }
++    }
++    video_enc->time_base.den= best->num;
++    video_enc->time_base.num= best->den;
++  }
++
++  video_enc->width  = params_.ni_;
++  video_enc->height = params_.nj_;
++  video_enc->sample_aspect_ratio = av_d2q(params_.frame_aspect_ratio_*params_.ni_/params_.nj_, 255);
++
++  // Our source is packed RGB. Use that if possible.
++  video_enc->pix_fmt = PIX_FMT_RGB24;
++  if ( codec && codec->pix_fmts )
++  {
++    const enum PixelFormat* p= codec->pix_fmts;
++    for ( ; *p != -1; p++ )
++    {
++      if ( *p == video_enc->pix_fmt )
++        break;
++    }
++    if ( *p == -1 )
++      video_enc->pix_fmt = codec->pix_fmts[0];
++  }
++  else if ( codec && ( codec->id == CODEC_ID_RAWVIDEO ||
++                      codec->id == CODEC_ID_HUFFYUV ) )
++  {
++    // these formats only support the YUV input image formats
++    video_enc->pix_fmt = PIX_FMT_YUV420P;
++  }
++
++  if (!params_.intra_only_)
++    video_enc->gop_size = params_.gop_size_;
++  else
++    video_enc->gop_size = 0;
++  if (params_.video_qscale_ || params_.same_quality_)
++  {
++    video_enc->flags |= CODEC_FLAG_QSCALE;
++    st->quality = FF_QP2LAMBDA * params_.video_qscale_;
++  }
++  // if (bitexact)
++  //   video_enc->flags |= CODEC_FLAG_BITEXACT;
++
++  video_enc->mb_decision = params_.mb_decision_;
++  video_enc->mb_cmp = params_.mb_cmp_;
++  video_enc->ildct_cmp = params_.ildct_cmp_;
++  video_enc->me_sub_cmp = params_.sub_cmp_;
++  video_enc->me_cmp = params_.cmp_;
++  video_enc->me_pre_cmp = params_.pre_cmp_;
++  video_enc->pre_me = params_.pre_me_;
++  video_enc->lumi_masking = params_.lumi_mask_;
++  video_enc->dark_masking = params_.dark_mask_;
++  video_enc->spatial_cplx_masking = params_.scplx_mask_;
++  video_enc->temporal_cplx_masking = params_.tcplx_mask_;
++  video_enc->p_masking = params_.p_mask_;
++  video_enc->quantizer_noise_shaping= params_.qns_;
++
++  if (params_.use_umv_)
++  {
++    video_enc->flags |= CODEC_FLAG_H263P_UMV;
++  }
++  if (params_.use_ss_)
++  {
++    video_enc->flags |= CODEC_FLAG_H263P_SLICE_STRUCT;
++  }
++  if (params_.use_aiv_)
++  {
++    video_enc->flags |= CODEC_FLAG_H263P_AIV;
++  }
++  if (params_.use_4mv_)
++  {
++    video_enc->flags |= CODEC_FLAG_4MV;
++  }
++  if (params_.use_obmc_)
++  {
++    video_enc->flags |= CODEC_FLAG_OBMC;
++  }
++  if (params_.use_loop_)
++  {
++    video_enc->flags |= CODEC_FLAG_LOOP_FILTER;
++  }
++
++  if (params_.use_part_)
++  {
++    video_enc->flags |= CODEC_FLAG_PART;
++  }
++  if (params_.use_alt_scan_)
++  {
++    video_enc->flags |= CODEC_FLAG_ALT_SCAN;
++  }
++  if (params_.use_scan_offset_)
++  {
++    video_enc->flags |= CODEC_FLAG_SVCD_SCAN_OFFSET;
++  }
++  if (params_.closed_gop_)
++  {
++    video_enc->flags |= CODEC_FLAG_CLOSED_GOP;
++  }
++  if (params_.use_qpel_)
++  {
++    video_enc->flags |= CODEC_FLAG_QPEL;
++  }
++  if (params_.use_qprd_)
++  {
++    video_enc->flags |= CODEC_FLAG_QP_RD;
++  }
++  if (params_.use_cbprd_)
++  {
++    video_enc->flags |= CODEC_FLAG_CBP_RD;
++  }
++  if (params_.b_frames_)
++  {
++    video_enc->max_b_frames = params_.b_frames_;
++    video_enc->b_frame_strategy = 0;
++    video_enc->b_quant_factor = 2.0;
++  }
++  if (params_.do_interlace_dct_)
++  {
++    video_enc->flags |= CODEC_FLAG_INTERLACED_DCT;
++  }
++  if (params_.do_interlace_me_)
++  {
++    video_enc->flags |= CODEC_FLAG_INTERLACED_ME;
++  }
++  video_enc->qmin = params_.video_qmin_;
++  video_enc->qmax = params_.video_qmax_;
++  video_enc->lmin = params_.video_lmin_;
++  video_enc->lmax = params_.video_lmax_;
++  video_enc->max_qdiff = params_.video_qdiff_;
++  video_enc->qblur = params_.video_qblur_;
++  video_enc->qcompress = params_.video_qcomp_;
++
++  // delete when the stream is closed
++  os_->video_rc_eq_ = new char[params_.video_rc_eq_.length()+1];
++  vcl_strcpy(os_->video_rc_eq_, params_.video_rc_eq_.c_str());
++  video_enc->rc_eq = os_->video_rc_eq_;
++
++  video_enc->debug = params_.debug_;
++  video_enc->debug_mv = params_.debug_mv_;
++  video_enc->thread_count = 1;
++
++  video_enc->rc_max_rate = params_.video_rc_max_rate_;
++  video_enc->rc_min_rate = params_.video_rc_min_rate_;
++  video_enc->rc_buffer_size = params_.video_rc_buffer_size_;
++  video_enc->rc_buffer_aggressivity= params_.video_rc_buffer_aggressivity_;
++  video_enc->rc_initial_cplx= params_.video_rc_initial_cplx_;
++  video_enc->i_quant_factor = params_.video_i_qfactor_;
++  video_enc->b_quant_factor = params_.video_b_qfactor_;
++  video_enc->i_quant_offset = params_.video_i_qoffset_;
++  video_enc->b_quant_offset = params_.video_b_qoffset_;
++  video_enc->intra_quant_bias = params_.video_intra_quant_bias_;
++  video_enc->inter_quant_bias = params_.video_inter_quant_bias_;
++  video_enc->dct_algo = params_.dct_algo_;
++  video_enc->idct_algo = params_.idct_algo_;
++  video_enc->me_threshold= params_.me_threshold_;
++  video_enc->mb_threshold= params_.mb_threshold_;
++  video_enc->intra_dc_precision= params_.intra_dc_precision_ - 8;
++  video_enc->strict_std_compliance = params_.strict_;
++  video_enc->error_rate = params_.error_rate_;
++  video_enc->noise_reduction= params_.noise_reduction_;
++  video_enc->scenechange_threshold= params_.sc_threshold_;
++  video_enc->me_range = params_.me_range_;
++  video_enc->coder_type= params_.coder_;
++  video_enc->context_model= params_.context_;
++  video_enc->prediction_method= params_.predictor_;
++
++  if (params_.do_psnr_)
++    video_enc->flags|= CODEC_FLAG_PSNR;
++
++  video_enc->me_method = params_.me_method_;
++
++  // two pass mode
++  if (params_.do_pass_)
++  {
++    if (params_.do_pass_ == 1)
++    {
++      video_enc->flags |= CODEC_FLAG_PASS1;
++    }
++    else
++    {
++      video_enc->flags |= CODEC_FLAG_PASS2;
++    }
++  }
++
++  vcl_strncpy( os_->fmt_cxt_->filename, filename_.c_str(), 1023 );
++
++  if ( avio_open( &os_->fmt_cxt_->pb, filename_.c_str(), URL_WRONLY) < 0 )
++  {
++    vcl_cerr << "ffmpeg: couldn't open " << filename_ << " for writing\n";
++    close();
++    return false;
++  }
++  os_->file_opened_ = true;
++
++  //dump_format( os_->fmt_cxt_, 1, filename_, 1 );
++
++  if ( avcodec_open( video_enc, codec ) < 0 )
++  {
++    vcl_cerr << "ffmpeg: couldn't open codec\n";
++    close();
++    return false;
++  }
++  os_->codec_opened_ = true;
++
++  if ( avformat_write_header( os_->fmt_cxt_, NULL ) < 0 )
++  {
++    vcl_cerr << "ffmpeg: couldn't write header\n";
++    close();
++    return false;
++  }
++
++  return true;
++}
++
++
++//: Close the stream
++void
++vidl_ffmpeg_ostream::
++close()
++{
++  delete os_->video_rc_eq_;
++  os_->video_rc_eq_ = NULL;
++
++  if ( os_->fmt_cxt_ ) {
++
++    if ( os_->file_opened_ ) {
++      av_write_trailer( os_->fmt_cxt_ );
++      avio_close( os_->fmt_cxt_->pb );
++      os_->file_opened_ = false;
++    }
++
++    if ( os_->fmt_cxt_->nb_streams > 0 ) {
++      if ( os_->codec_opened_ ) {
++        for ( unsigned i = 0; i < os_->fmt_cxt_->nb_streams; ++i ) {
++          AVCodecContext* codec = os_->fmt_cxt_->streams[i]->codec;
++          if ( codec->stats_in ) {
++            av_freep( codec->stats_in );
++          }
++          avcodec_close( codec );
++        }
++      }
++      os_->codec_opened_ = false;
++      for ( unsigned i = 0; i < os_->fmt_cxt_->nb_streams; ++i ) {
++        av_free( os_->fmt_cxt_->streams[i] );
++      }
++    }
++
++    av_free( os_->fmt_cxt_ );
++    os_->fmt_cxt_ = 0;
++  }
++}
++
++
++//: Return true if the stream is open for writing
++bool
++vidl_ffmpeg_ostream::
++is_open() const
++{
++  return os_->file_opened_;
++}
++
++
++//: Write and image to the stream
++// \retval false if the image could not be written
++bool
++vidl_ffmpeg_ostream::
++write_frame(const vidl_frame_sptr& frame)
++{
++  if (!is_open()) {
++    // resize to the first frame
++    params_.size(frame->ni(),frame->nj());
++    open();
++  }
++
++  AVCodecContext* codec = os_->fmt_cxt_->streams[0]->codec;
++
++  if (unsigned( codec->width ) != frame->ni() ||
++      unsigned( codec->height) != frame->nj() ) {
++    vcl_cerr << "ffmpeg: Input image has wrong size. Expecting ("
++             << codec->width << 'x' << codec->height << "), got ("
++             << frame->ni() << 'x' << frame->nj() << ")\n";
++    return false;
++  }
++
++  PixelFormat fmt = vidl_pixel_format_to_ffmpeg(frame->pixel_format());
++
++  vidl_pixel_format target_fmt = vidl_pixel_format_from_ffmpeg(codec->pix_fmt);
++  static vidl_frame_sptr temp_frame = new vidl_shared_frame(NULL,frame->ni(),frame->nj(),target_fmt);
++
++  AVFrame out_frame;
++  avcodec_get_frame_defaults( &out_frame );
++
++  // The frame is in the correct format to encode directly
++  if ( codec->pix_fmt == fmt )
++  {
++    avpicture_fill((AVPicture*)&out_frame, (uint8_t*) frame->data(),
++                   fmt, frame->ni(), frame->nj());
++  }
++  else
++  {
++    if (!temp_frame->data()) {
++      unsigned ni = frame->ni();
++      unsigned nj = frame->nj();
++      unsigned out_size = vidl_pixel_format_buffer_size(ni,nj,target_fmt);
++      temp_frame = new vidl_memory_chunk_frame(ni, nj, target_fmt,
++                                               new vil_memory_chunk(out_size, VIL_PIXEL_FORMAT_BYTE));
++    }
++    // try conversion with FFMPEG functions
++    if (!vidl_ffmpeg_convert(frame, temp_frame)) {
++      // try conversion with vidl functions
++      if (!vidl_convert_frame(*frame, *temp_frame)) {
++        vcl_cout << "unable to convert " << frame->pixel_format() << " to "<<target_fmt<<vcl_endl;
++        return false;
++      }
++    }
++    avpicture_fill((AVPicture*)&out_frame, (uint8_t*) temp_frame->data(),
++                   codec->pix_fmt, frame->ni(), frame->nj());
++  }
++
++  AVPacket pkt;
++  av_init_packet( &pkt );
++  pkt.stream_index = 0;
++
++  out_frame.pts = os_->cur_frame_;
++
++  int ret = avcodec_encode_video( codec, (uint8_t*)os_->bit_buf_->data(), os_->bit_buf_->size(), &out_frame );
++
++  if ( ret ) {
++    pkt.data = (uint8_t*)os_->bit_buf_->data();
++    pkt.size = ret;
++    if ( codec->coded_frame ) {
++      pkt.pts = codec->coded_frame->pts;
++    }
++    if ( codec->coded_frame && codec->coded_frame->key_frame ) {
++      pkt.flags |= AV_PKT_FLAG_KEY;
++    }
++    av_interleaved_write_frame( os_->fmt_cxt_, &pkt );
++  }
++  else {
++    return false;
++  }
++
++  ++os_->cur_frame_;
++  return true;
++}
++
++#endif // vidl_ffmpeg_ostream_v3_txx_
+Index: vxl-1.14.0/core/vidl/vidl_ffmpeg_istream_v3.txx
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ vxl-1.14.0/core/vidl/vidl_ffmpeg_istream_v3.txx	2011-12-20 11:07:57.000000000 +0100
+@@ -0,0 +1,569 @@
++// This is core/vidl/vidl_ffmpeg_istream_v3.txx
++#ifndef vidl_ffmpeg_istream_v3_txx_
++#define vidl_ffmpeg_istream_v3_txx_
++#include "vidl_ffmpeg_istream.h"
++//:
++// \file
++// \author Matt Leotta
++// \author Amitha Perera
++// \date   3 Nov 2011
++//
++// Update implementation based on
++// ffmpeg git hash 139f3ac42dcf24eb8c59af4aaab4e9afdccbc996
++
++//-----------------------------------------------------------------------------
++
++#include "vidl_ffmpeg_init.h"
++#include "vidl_frame.h"
++#include "vidl_ffmpeg_convert.h"
++
++#include <vcl_string.h>
++#include <vcl_iostream.h>
++
++extern "C" {
++#if FFMPEG_IN_SEVERAL_DIRECTORIES
++#include <libavcodec/avcodec.h>
++#include <libavformat/avformat.h>
++#include <libswscale/swscale.h>
++#else
++#include <ffmpeg/avcodec.h>
++#include <ffmpeg/avformat.h>
++#include <ffmpeg/swscale.h>
++#endif
++}
++
++//--------------------------------------------------------------------------------
++
++struct vidl_ffmpeg_istream::pimpl
++{
++  pimpl()
++  : fmt_cxt_( NULL ),
++    vid_index_( -1 ),
++    vid_str_( NULL ),
++    last_dts( 0 ),
++    frame_( NULL ),
++    num_frames_( -2 ), // sentinel value to indicate not yet computed
++    sws_context_( NULL ),
++    cur_frame_( NULL ),
++    deinterlace_( false ),
++    frame_number_offset_( 0 )
++  {
++  }
++
++  AVFormatContext* fmt_cxt_;
++  int vid_index_;
++  AVStream* vid_str_;
++
++  //: Decode time of last frame.
++  int64_t last_dts;
++
++  //: Start time of the stream, to offset the dts when computing the frame number.
++  int64_t start_time;
++
++  //: The last successfully read frame.
++  //
++  // If frame_->data[0] is not NULL, then the frame corresponds to
++  // the codec state, so that codec.width and so on apply to the
++  // frame data.
++  AVFrame* frame_;
++
++  //: number of counted frames
++  int num_frames_;
++
++  //: A software scaling context
++  //
++  // This is the context used for the software scaling and colour
++  // conversion routines. Since the conversion is likely to be the
++  // same for each frame, we save the context to avoid re-creating it
++  // every time.
++  SwsContext* sws_context_;
++
++  //: A contiguous memory buffer to store the current image data
++  vil_memory_chunk_sptr contig_memory_;
++
++  //: The last successfully decoded frame.
++  mutable vidl_frame_sptr cur_frame_;
++
++  //: Apply deinterlacing on the frames?
++  bool deinterlace_;
++
++  //: Some codec/file format combinations need a frame number offset.
++  // These codecs have a delay between reading packets and generating frames.
++  unsigned frame_number_offset_;
++};
++
++
++//--------------------------------------------------------------------------------
++
++//: Constructor
++vidl_ffmpeg_istream::
++vidl_ffmpeg_istream()
++  : is_( new vidl_ffmpeg_istream::pimpl )
++{
++  vidl_ffmpeg_init();
++}
++
++
++//: Constructor - from a filename
++vidl_ffmpeg_istream::
++vidl_ffmpeg_istream(const vcl_string& filename)
++  : is_( new vidl_ffmpeg_istream::pimpl )
++{
++  vidl_ffmpeg_init();
++  open(filename);
++}
++
++
++//: Destructor
++vidl_ffmpeg_istream::
++~vidl_ffmpeg_istream()
++{
++  close();
++  delete is_;
++}
++
++//: Open a new stream using a filename
++bool
++vidl_ffmpeg_istream::
++open(const vcl_string& filename)
++{
++  // Close any currently opened file
++  close();
++
++  // Open the file
++  int err;
++  if ( ( err = avformat_open_input( &is_->fmt_cxt_, filename.c_str(), NULL, NULL ) ) != 0 ) {
++    return false;
++  }
++
++  // Get the stream information by reading a bit of the file
++  if ( av_find_stream_info( is_->fmt_cxt_ ) < 0 ) {
++    return false;
++  }
++
++  // Find a video stream. Use the first one we find.
++  is_->vid_index_ = -1;
++  for ( unsigned i = 0; i < is_->fmt_cxt_->nb_streams; ++i ) {
++    AVCodecContext *enc = is_->fmt_cxt_->streams[i]->codec;
++    if ( enc->codec_type == AVMEDIA_TYPE_VIDEO ) {
++      is_->vid_index_ = i;
++      break;
++    }
++  }
++  if ( is_->vid_index_ == -1 ) {
++    return false;
++  }
++
++  av_dump_format( is_->fmt_cxt_, 0, filename.c_str(), 0 );
++  AVCodecContext *enc = is_->fmt_cxt_->streams[is_->vid_index_]->codec;
++
++  // Open the stream
++  AVCodec* codec = avcodec_find_decoder(enc->codec_id);
++  if ( !codec || avcodec_open( enc, codec ) < 0 ) {
++    return false;
++  }
++
++  is_->vid_str_ = is_->fmt_cxt_->streams[ is_->vid_index_ ];
++  is_->frame_ = avcodec_alloc_frame();
++
++  if ( is_->vid_str_->start_time == int64_t(1)<<63 ) {
++    is_->start_time = 0;
++  }
++  else {
++    is_->start_time = is_->vid_str_->start_time;
++  }
++
++  // The MPEG 2 codec has a latency of 1 frame when encoded in an AVI
++  // stream, so the dts of the last packet (stored in last_dts) is
++  // actually the next frame's dts.
++  if ( is_->vid_str_->codec->codec_id == CODEC_ID_MPEG2VIDEO &&
++       vcl_string("avi") == is_->fmt_cxt_->iformat->name ) {
++    is_->frame_number_offset_ = 1;
++  }
++
++  return true;
++}
++
++
++//: Close the stream
++void
++vidl_ffmpeg_istream::
++close()
++{
++  if ( is_->frame_ ) {
++    av_freep( &is_->frame_ );
++  }
++
++  is_->num_frames_ = -2;
++  is_->contig_memory_ = 0;
++  is_->vid_index_ = -1;
++  if ( is_->vid_str_ ) {
++    avcodec_close( is_->vid_str_->codec );
++    is_->vid_str_ = 0;
++  }
++  if ( is_->fmt_cxt_ ) {
++    av_close_input_file( is_->fmt_cxt_ );
++    is_->fmt_cxt_ = 0;
++  }
++}
++
++
++//: Return true if the stream is open for reading
++bool
++vidl_ffmpeg_istream::
++is_open() const
++{
++  return ! ! is_->frame_;
++}
++
++
++//: Return true if the stream is in a valid state
++bool
++vidl_ffmpeg_istream::
++is_valid() const
++{
++  return is_open() && is_->frame_->data[0] != 0;
++}
++
++
++//: Return true if the stream support seeking
++bool
++vidl_ffmpeg_istream::
++is_seekable() const
++{
++  return true;
++}
++
++
++//: Return the number of frames if known
++//  returns -1 for non-seekable streams
++int
++vidl_ffmpeg_istream::num_frames() const
++{
++  // to get an accurate frame count, quickly run through the entire
++  // video.  We'll only do this if the user hasn't read any frames,
++  // because we have no guarantee that we can successfully seek back
++  // to anywhere but the beginning.  There is logic in advance() to
++  // ensure this.
++  vidl_ffmpeg_istream* mutable_this = const_cast<vidl_ffmpeg_istream*>(this);
++  if ( mutable_this->is_->num_frames_ == -2 ) {
++    mutable_this->is_->num_frames_ = 0;
++    while (mutable_this->advance()) {
++      ++mutable_this->is_->num_frames_;
++    }
++    av_seek_frame( mutable_this->is_->fmt_cxt_,
++                   mutable_this->is_->vid_index_,
++                   0,
++                   AVSEEK_FLAG_BACKWARD );
++  }
++
++  return is_->num_frames_;
++}
++
++
++//: Return the current frame number
++unsigned int
++vidl_ffmpeg_istream::
++frame_number() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_valid() ) {
++    return static_cast<unsigned int>(-1);
++  }
++
++  return ((is_->last_dts - is_->start_time)
++          * is_->vid_str_->r_frame_rate.num / is_->vid_str_->r_frame_rate.den
++          * is_->vid_str_->time_base.num + is_->vid_str_->time_base.den/2)
++         / is_->vid_str_->time_base.den
++         - int(is_->frame_number_offset_);
++}
++
++
++//: Return the width of each frame
++unsigned int
++vidl_ffmpeg_istream
++::width() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return 0;
++  }
++
++  return is_->fmt_cxt_->streams[is_->vid_index_]->codec->width;
++}
++
++
++//: Return the height of each frame
++unsigned int
++vidl_ffmpeg_istream
++::height() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return 0;
++  }
++
++  return is_->fmt_cxt_->streams[is_->vid_index_]->codec->height;
++}
++
++
++//: Return the pixel format
++vidl_pixel_format
++vidl_ffmpeg_istream
++::format() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return VIDL_PIXEL_FORMAT_UNKNOWN;
++  }
++
++  AVCodecContext* enc = is_->fmt_cxt_->streams[is_->vid_index_]->codec;
++  vidl_pixel_format fmt = vidl_pixel_format_from_ffmpeg(enc->pix_fmt);
++  if (fmt == VIDL_PIXEL_FORMAT_UNKNOWN)
++    return VIDL_PIXEL_FORMAT_RGB_24;
++  return fmt;
++}
++
++
++//: Return the frame rate (0.0 if unspecified)
++double
++vidl_ffmpeg_istream
++::frame_rate() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return 0.0;
++  }
++
++  return static_cast<double>(is_->vid_str_->r_frame_rate.num) / is_->vid_str_->r_frame_rate.den;
++}
++
++
++//: Return the duration in seconds (0.0 if unknown)
++double
++vidl_ffmpeg_istream
++::duration() const
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return 0.0;
++  }
++  return static_cast<double>(is_->vid_str_->time_base.num)/is_->vid_str_->time_base.den
++         * static_cast<double>(is_->vid_str_->duration);
++}
++
++
++//: Advance to the next frame (but don't acquire an image)
++bool
++vidl_ffmpeg_istream::
++advance()
++{
++  // Quick return if the file isn't open.
++  if ( !is_open() ) {
++    return false;
++  }
++
++  // See the comment in num_frames().  This is to make sure that once
++  // we start reading frames, we'll never try to march to the end to
++  // figure out how many frames there are.
++  if ( is_->num_frames_ == -2 ) {
++    is_->num_frames_ = -1;
++  }
++
++  AVCodecContext* codec = is_->fmt_cxt_->streams[is_->vid_index_]->codec;
++
++  AVPacket pkt;
++  int got_picture = 0;
++
++  while ( got_picture == 0 ) {
++    if ( av_read_frame( is_->fmt_cxt_, &pkt ) < 0 ) {
++      break;
++    }
++    is_->last_dts = pkt.dts;
++
++    // Make sure that the packet is from the actual video stream.
++    if (pkt.stream_index==is_->vid_index_)
++    {
++      if ( avcodec_decode_video2( codec,
++                                  is_->frame_, &got_picture,
++                                  &pkt ) < 0 ) {
++        vcl_cerr << "vidl_ffmpeg_istream: Error decoding packet!\n";
++        return false;
++      }
++    }
++    av_free_packet( &pkt );
++  }
++
++  // From ffmpeg apiexample.c: some codecs, such as MPEG, transmit the
++  // I and P frame with a latency of one frame. You must do the
++  // following to have a chance to get the last frame of the video.
++  if ( !got_picture ) {
++    av_init_packet(&pkt);
++    pkt.data = NULL;
++    pkt.size = 0;
++    if ( avcodec_decode_video2( codec,
++                                is_->frame_, &got_picture,
++                                &pkt ) >= 0 ) {
++      is_->last_dts += int64_t(is_->vid_str_->time_base.den) * is_->vid_str_->r_frame_rate.den
++        / is_->vid_str_->time_base.num / is_->vid_str_->r_frame_rate.num;
++    }
++  }
++
++  // The cached frame is out of date, whether we managed to get a new
++  // frame or not.
++  if (is_->cur_frame_)
++    is_->cur_frame_->invalidate();
++  is_->cur_frame_ = 0;
++
++  if ( ! got_picture ) {
++    is_->frame_->data[0] = NULL;
++  }
++
++  return got_picture != 0;
++}
++
++
++//: Read the next frame from the stream
++vidl_frame_sptr
++vidl_ffmpeg_istream::read_frame()
++{
++  if (advance())
++    return current_frame();
++  return NULL;
++}
++
++
++//: Return the current frame in the stream
++vidl_frame_sptr
++vidl_ffmpeg_istream::current_frame()
++{
++  // Quick return if the stream isn't valid
++  if ( !is_valid() ) {
++    return NULL;
++  }
++  AVCodecContext* enc = is_->fmt_cxt_->streams[is_->vid_index_]->codec;
++  // If we have not already converted this frame, try to convert it
++  if ( !is_->cur_frame_ && is_->frame_->data[0] != 0 )
++  {
++    int width = enc->width;
++    int height = enc->height;
++
++    // Deinterlace if requested
++    if ( is_->deinterlace_ ) {
++      avpicture_deinterlace( (AVPicture*)is_->frame_, (AVPicture*)is_->frame_,
++                             enc->pix_fmt, width, height );
++    }
++
++    // If the pixel format is not recognized by vidl then convert the data into RGB_24
++    vidl_pixel_format fmt = vidl_pixel_format_from_ffmpeg(enc->pix_fmt);
++    if (fmt == VIDL_PIXEL_FORMAT_UNKNOWN)
++    {
++      int size = width*height*3;
++      if (!is_->contig_memory_)
++        is_->contig_memory_ = new vil_memory_chunk(size, VIL_PIXEL_FORMAT_BYTE);
++      else
++        is_->contig_memory_->set_size(size, VIL_PIXEL_FORMAT_BYTE);
++
++      // Reuse the previous context if we can.
++      is_->sws_context_ = sws_getCachedContext(
++        is_->sws_context_,
++        width, height, enc->pix_fmt,
++        width, height, PIX_FMT_RGB24,
++        SWS_BILINEAR,
++        NULL, NULL, NULL );
++
++      if ( is_->sws_context_ == NULL ) {
++        vcl_cerr << "vidl_ffmpeg_istream: couldn't create conversion context\n";
++        return vidl_frame_sptr();
++      }
++
++      AVPicture rgb_frame;
++      avpicture_fill(&rgb_frame, (uint8_t*)is_->contig_memory_->data(), PIX_FMT_RGB24, width, height);
++
++      sws_scale( is_->sws_context_,
++                 is_->frame_->data, is_->frame_->linesize,
++                 0, height,
++                 rgb_frame.data, rgb_frame.linesize );
++
++      is_->cur_frame_ = new vidl_shared_frame(is_->contig_memory_->data(),width,height,
++                                              VIDL_PIXEL_FORMAT_RGB_24);
++    }
++    else
++    {
++      // Test for contiguous memory.  Sometimes FFMPEG uses scanline buffers larger
++      // than the image width.  The extra memory is used in optimized decoding routines.
++      // This leads to a segmented image buffer, not supported by vidl.
++      AVPicture test_frame;
++      avpicture_fill(&test_frame, is_->frame_->data[0], enc->pix_fmt, width, height);
++      if (test_frame.data[1] == is_->frame_->data[1] &&
++          test_frame.data[2] == is_->frame_->data[2] &&
++          test_frame.linesize[0] == is_->frame_->linesize[0] &&
++          test_frame.linesize[1] == is_->frame_->linesize[1] &&
++          test_frame.linesize[2] == is_->frame_->linesize[2] )
++      {
++        is_->cur_frame_ = new vidl_shared_frame(is_->frame_->data[0], width, height, fmt);
++      }
++      // Copy the image into contiguous memory.
++      else
++      {
++        if (!is_->contig_memory_) {
++          int size = avpicture_get_size( enc->pix_fmt, width, height );
++          is_->contig_memory_ = new vil_memory_chunk(size, VIL_PIXEL_FORMAT_BYTE);
++        }
++        avpicture_fill(&test_frame, (uint8_t*)is_->contig_memory_->data(), enc->pix_fmt, width, height);
++        av_picture_copy(&test_frame, (AVPicture*)is_->frame_, enc->pix_fmt, width, height);
++        // use a shared frame because the vil_memory_chunk is reused for each frame
++        is_->cur_frame_ = new vidl_shared_frame(is_->contig_memory_->data(),width,height,fmt);
++      }
++    }
++  }
++
++  return is_->cur_frame_;
++}
++
++
++//: Seek to the given frame number
++// \returns true if successful
++bool
++vidl_ffmpeg_istream::
++seek_frame(unsigned int frame)
++{
++  // Quick return if the stream isn't open.
++  if ( !is_open() ) {
++    return false;
++  }
++
++  // We rely on the initial cast to make sure all the operations happen in int64.
++  int64_t req_timestamp =
++    int64_t(frame + is_->frame_number_offset_)
++    * is_->vid_str_->time_base.den
++    * is_->vid_str_->r_frame_rate.den
++    / is_->vid_str_->time_base.num
++    / is_->vid_str_->r_frame_rate.num
++    + is_->start_time;
++
++  // Seek to a keyframe before the timestamp that we want.
++  int seek = av_seek_frame( is_->fmt_cxt_, is_->vid_index_, req_timestamp, AVSEEK_FLAG_BACKWARD );
++
++  if ( seek < 0 )
++    return false;
++
++  avcodec_flush_buffers( is_->vid_str_->codec );
++
++  // We got to a key frame. Forward until we get to the frame we want.
++  while ( true )
++  {
++    if ( ! advance() ) {
++      return false;
++    }
++    if ( is_->last_dts >= req_timestamp ) {
++      if ( is_->last_dts > req_timestamp ) {
++        vcl_cerr << "Warning: seek went into the future!\n";
++        return false;
++      }
++      return true;
++    }
++  }
++}
++
++#endif // vidl_ffmpeg_istream_v3_txx_
+Index: vxl-1.14.0/core/vidl/vidl_ffmpeg_istream.cxx
+===================================================================
+--- vxl-1.14.0.orig/core/vidl/vidl_ffmpeg_istream.cxx	2009-09-20 23:34:34.000000000 +0200
++++ vxl-1.14.0/core/vidl/vidl_ffmpeg_istream.cxx	2011-12-20 11:07:57.000000000 +0100
+@@ -23,8 +23,10 @@
+ 
+ #if LIBAVFORMAT_BUILD < ((52<<16)+(2<<8)+0)  // before ver 52.2.0
+ # include "vidl_ffmpeg_istream_v1.txx"
+-#else
++#elif LIBAVFORMAT_BUILD < ((53<<16)+(0<<8)+0)  // before ver 53.0.0
+ # include "vidl_ffmpeg_istream_v2.txx"
++#else
++# include "vidl_ffmpeg_istream_v3.txx"
+ #endif
+ 
+ #else // VIDL_HAS_FFMPEG
+Index: vxl-1.14.0/core/vidl/vidl_ffmpeg_ostream.cxx
+===================================================================
+--- vxl-1.14.0.orig/core/vidl/vidl_ffmpeg_ostream.cxx	2009-09-20 23:34:34.000000000 +0200
++++ vxl-1.14.0/core/vidl/vidl_ffmpeg_ostream.cxx	2011-12-20 11:07:57.000000000 +0100
+@@ -23,8 +23,10 @@
+ # include "vidl_ffmpeg_ostream_v1.txx"
+ #elif LIBAVCODEC_BUILD < ((52<<16)+(10<<8)+0)  // before ver 52.10.0
+ # include "vidl_ffmpeg_ostream_v2.txx"
+-#else
++#elif LIBAVCODEC_BUILD < ((53<<16)+(0<<8)+0)  // before ver 53.0.0
+ # include "vidl_ffmpeg_ostream_v3.txx"
++#else
++# include "vidl_ffmpeg_ostream_v4.txx"
+ #endif
+ 
+ #else // VIDL_HAS_FFMPEG
+Index: vxl-1.14.0/core/vidl/CMakeLists.txt
+===================================================================
+--- vxl-1.14.0.orig/core/vidl/CMakeLists.txt	2011-12-20 11:06:25.000000000 +0100
++++ vxl-1.14.0/core/vidl/CMakeLists.txt	2011-12-20 11:09:20.000000000 +0100
+@@ -75,7 +75,8 @@
+       vidl_ffmpeg_convert.h          vidl_ffmpeg_convert.cxx
+       vidl_ffmpeg_istream_v1.txx     vidl_ffmpeg_ostream_v1.txx
+       vidl_ffmpeg_istream_v2.txx     vidl_ffmpeg_ostream_v2.txx
+-                                     vidl_ffmpeg_ostream_v3.txx
++      vidl_ffmpeg_istream_v3.txx     vidl_ffmpeg_ostream_v3.txx
++                                     vidl_ffmpeg_ostream_v4.txx
+   )
+ # Stub implementation, when ffmeg is not available
+ ELSE( FFMPEG_FOUND )

Modified: trunk/packages/vxl/trunk/debian/patches/series
===================================================================
--- trunk/packages/vxl/trunk/debian/patches/series	2011-12-20 09:59:31 UTC (rev 9055)
+++ trunk/packages/vxl/trunk/debian/patches/series	2011-12-20 10:10:35 UTC (rev 9056)
@@ -1,5 +1,3 @@
-fix_libav07.patch
-ffmpeg_C99.patch
 vxl.soname.patch
 video4linux.patch
 opencl_unix.patch
@@ -8,3 +6,4 @@
 fixcomp.patch
 fix_alphacomp.patch
 install_doxygen.patch
+libav_trunk.patch




More information about the debian-med-commit mailing list