This repository has been archived on 2023-10-09. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
blender-archive/source/blender/imbuf/intern/util.c
Peter Schlaile c07bd1439a == Sequencer ==
This patch adds:

* support for proxy building again (missing feature from Blender 2.49)
  additionally to the way, Blender 2.49 worked, you can select several
  strips at once and make Blender build proxies in the background (using
  the job system)
  Also a new thing: movie proxies are now build into AVI files, and
  the proxy system is moved into ImBuf-library, so that other parts
  of blender can also benefit from it.
  
* Timecode support: to fix seeking issues with files, that have
  a) varying frame rates
  b) very large GOP lengths
  c) are broken inbetween
  d) use different time code tracks
  
  the proxy builder can now also build timecode indices, which are
  used (optionally) for seeking.
  
  For the first time, it is possible, to do frame exact seeking on
  all file types.
  
* Support for different video-streams in one video file (can be
  selected in sequencer, other parts of blender can also use it,
  but UI has to be added accordingly)

* IMPORTANT: this patch *requires* ffmpeg 0.7 or newer, since
  older versions don't support the pkt_pts field, that is essential
  for building timecode indices.
  
  Windows and Mac libs are already updated, Linux-users have to build
  their own ffmpeg verions until distros keep up.
2011-08-28 14:46:03 +00:00

402 lines
7.7 KiB
C

/*
*
* ***** BEGIN GPL LICENSE BLOCK *****
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
* The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
* All rights reserved.
*
* The Original Code is: all of this file.
*
* Contributor(s): none yet.
*
* ***** END GPL LICENSE BLOCK *****
* util.c
*
* $Id$
*/
/** \file blender/imbuf/intern/util.c
* \ingroup imbuf
*/
#ifdef _WIN32
#include <io.h>
#define open _open
#define read _read
#define close _close
#endif
#include "BLI_blenlib.h"
#include "DNA_userdef_types.h"
#include "BKE_global.h"
#include "imbuf.h"
#include "IMB_imbuf_types.h"
#include "IMB_imbuf.h"
#include "IMB_filetype.h"
#include "IMB_anim.h"
#ifdef WITH_QUICKTIME
#include "quicktime_import.h"
#endif
#ifdef WITH_FFMPEG
#include <libavcodec/avcodec.h>
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libavutil/log.h>
#include "ffmpeg_compat.h"
#endif
#define UTIL_DEBUG 0
const char *imb_ext_image[] = {
".png",
".tga",
".bmp",
".jpg", ".jpeg",
".sgi", ".rgb", ".rgba",
#ifdef WITH_TIFF
".tif", ".tiff", ".tx",
#endif
#ifdef WITH_OPENJPEG
".jp2",
#endif
#ifdef WITH_HDR
".hdr",
#endif
#ifdef WITH_DDS
".dds",
#endif
#ifdef WITH_CINEON
".dpx",
".cin",
#endif
#ifdef WITH_OPENEXR
".exr",
#endif
NULL};
const char *imb_ext_image_qt[] = {
".gif",
".psd",
".pct", ".pict",
".pntg",
".qtif",
NULL};
const char *imb_ext_movie[] = {
".avi",
".flc",
".mov",
".movie",
".mp4",
".m4v",
".m2v",
".m2t",
".m2ts",
".mts",
".mv",
".avs",
".wmv",
".ogv",
".dv",
".mpeg",
".mpg",
".mpg2",
".vob",
".mkv",
".flv",
".divx",
".xvid",
".mxf",
NULL};
/* sort of wrong being here... */
const char *imb_ext_audio[] = {
".wav",
".ogg",
".oga",
".mp3",
".mp2",
".ac3",
".aac",
".flac",
".wma",
".eac3",
".aif",
".aiff",
".m4a",
NULL};
static int IMB_ispic_name(const char *name)
{
ImFileType *type;
struct stat st;
int fp, buf[10];
if(UTIL_DEBUG) printf("IMB_ispic_name: loading %s\n", name);
if(stat(name,&st) == -1)
return FALSE;
if(((st.st_mode) & S_IFMT) != S_IFREG)
return FALSE;
if((fp = open(name,O_BINARY|O_RDONLY)) < 0)
return FALSE;
if(read(fp, buf, 32) != 32) {
close(fp);
return FALSE;
}
close(fp);
/* XXX move this exception */
if((BIG_LONG(buf[0]) & 0xfffffff0) == 0xffd8ffe0)
return JPG;
for(type=IMB_FILE_TYPES; type->is_a; type++)
if(type->is_a((uchar*)buf))
return type->filetype;
return FALSE;
}
int IMB_ispic(const char *filename)
{
if(U.uiflag & USER_FILTERFILEEXTS) {
if( (BLI_testextensie_array(filename, imb_ext_image)) ||
(G.have_quicktime && BLI_testextensie_array(filename, imb_ext_image_qt))
) {
return IMB_ispic_name(filename);
}
else {
return FALSE;
}
}
else { /* no FILTERFILEEXTS */
return IMB_ispic_name(filename);
}
}
static int isavi (const char *name) {
return AVI_is_avi (name);
}
#ifdef WITH_QUICKTIME
static int isqtime (const char *name) {
return anim_is_quicktime (name);
}
#endif
#ifdef WITH_FFMPEG
void silence_log_ffmpeg(int quiet)
{
if (quiet)
{
av_log_set_level(AV_LOG_QUIET);
}
else
{
av_log_set_level(AV_LOG_DEBUG);
}
}
extern void do_init_ffmpeg(void);
void do_init_ffmpeg(void)
{
static int ffmpeg_init = 0;
if (!ffmpeg_init) {
ffmpeg_init = 1;
av_register_all();
avdevice_register_all();
if ((G.f & G_DEBUG) == 0) {
silence_log_ffmpeg(1);
} else {
silence_log_ffmpeg(0);
}
}
}
static int isffmpeg (const char *filename) {
AVFormatContext *pFormatCtx;
unsigned int i;
int videoStream;
AVCodec *pCodec;
AVCodecContext *pCodecCtx;
do_init_ffmpeg();
if( BLI_testextensie(filename, ".swf") ||
BLI_testextensie(filename, ".jpg") ||
BLI_testextensie(filename, ".png") ||
BLI_testextensie(filename, ".dds") ||
BLI_testextensie(filename, ".tga") ||
BLI_testextensie(filename, ".bmp") ||
BLI_testextensie(filename, ".exr") ||
BLI_testextensie(filename, ".cin") ||
BLI_testextensie(filename, ".wav")) return 0;
if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_open_input_file failed\n");
return 0;
}
if(av_find_stream_info(pFormatCtx)<0) {
if(UTIL_DEBUG) fprintf(stderr, "isffmpeg: av_find_stream_info failed\n");
av_close_input_file(pFormatCtx);
return 0;
}
if(UTIL_DEBUG) av_dump_format(pFormatCtx, 0, filename, 0);
/* Find the first video stream */
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(pFormatCtx->streams[i] &&
pFormatCtx->streams[i]->codec &&
(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO))
{
videoStream=i;
break;
}
if(videoStream==-1) {
av_close_input_file(pFormatCtx);
return 0;
}
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
/* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);
if(pCodec==NULL) {
av_close_input_file(pFormatCtx);
return 0;
}
if(avcodec_open(pCodecCtx, pCodec)<0) {
av_close_input_file(pFormatCtx);
return 0;
}
avcodec_close(pCodecCtx);
av_close_input_file(pFormatCtx);
return 1;
}
#endif
#ifdef WITH_REDCODE
static int isredcode(const char * filename)
{
struct redcode_handle * h = redcode_open(filename);
if (!h) {
return 0;
}
redcode_close(h);
return 1;
}
#endif
int imb_get_anim_type(const char * name) {
int type;
struct stat st;
if(UTIL_DEBUG) printf("in getanimtype: %s\n", name);
#ifndef _WIN32
# ifdef WITH_QUICKTIME
if (isqtime(name)) return (ANIM_QTIME);
# endif
# ifdef WITH_FFMPEG
/* stat test below fails on large files > 4GB */
if (isffmpeg(name)) return (ANIM_FFMPEG);
# endif
if (stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
if (isavi(name)) return (ANIM_AVI);
if (ismovie(name)) return (ANIM_MOVIE);
#else
if (stat(name,&st) == -1) return(0);
if (((st.st_mode) & S_IFMT) != S_IFREG) return(0);
if (ismovie(name)) return (ANIM_MOVIE);
# ifdef WITH_QUICKTIME
if (isqtime(name)) return (ANIM_QTIME);
# endif
# ifdef WITH_FFMPEG
if (isffmpeg(name)) return (ANIM_FFMPEG);
# endif
if (isavi(name)) return (ANIM_AVI);
#endif
#ifdef WITH_REDCODE
if (isredcode(name)) return (ANIM_REDCODE);
#endif
type = IMB_ispic(name);
if (type) return(ANIM_SEQUENCE);
return(0);
}
int IMB_isanim(const char *filename) {
int type;
if(U.uiflag & USER_FILTERFILEEXTS) {
if (G.have_quicktime){
if( BLI_testextensie(filename, ".avi")
|| BLI_testextensie(filename, ".flc")
|| BLI_testextensie(filename, ".dv")
|| BLI_testextensie(filename, ".r3d")
|| BLI_testextensie(filename, ".mov")
|| BLI_testextensie(filename, ".movie")
|| BLI_testextensie(filename, ".mv")) {
type = imb_get_anim_type(filename);
} else {
return(FALSE);
}
} else { // no quicktime
if( BLI_testextensie(filename, ".avi")
|| BLI_testextensie(filename, ".dv")
|| BLI_testextensie(filename, ".r3d")
|| BLI_testextensie(filename, ".mv")) {
type = imb_get_anim_type(filename);
}
else {
return(FALSE);
}
}
} else { // no FILTERFILEEXTS
type = imb_get_anim_type(filename);
}
return (type && type!=ANIM_SEQUENCE);
}