[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