== FFMPEG ==

* removed a lot of old cruft code for ancient ffmpeg versions
* made it compile again against latest ffmpeg / libav GIT
  (also shouldn't break distro ffmpegs, since those API changes
  have been introduced over a year ago. If it nevertheless breaks,
  please send me an email)
This commit is contained in:
Peter Schlaile
2011-05-26 21:57:02 +00:00
parent 78b8e4a437
commit 4b9a63c6d3
7 changed files with 68 additions and 135 deletions

View File

@@ -52,6 +52,10 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)
int read_length, data_size;
AVPacket tmp_pkt;
av_init_packet(&tmp_pkt);
// as long as there is still data in the package
while(audio_pkg_size > 0)
{
@@ -64,15 +68,14 @@ int AUD_FFMPEGReader::decode(AVPacket* packet, AUD_Buffer& buffer)
// read samples from the packet
data_size = buf_size - buf_pos;
/*read_length = avcodec_decode_audio3(m_codecCtx,
(int16_t*)(((data_t*)buffer.getBuffer())+buf_pos),
&data_size,
packet);*/
read_length = avcodec_decode_audio2(m_codecCtx,
(int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
&data_size,
audio_pkg_data,
audio_pkg_size);
tmp_pkt.data = audio_pkg_data;
tmp_pkt.size = audio_pkg_size;
read_length = avcodec_decode_audio3(
m_codecCtx,
(int16_t*)(((data_t*)buffer.getBuffer()) + buf_pos),
&data_size, &tmp_pkt);
// read error, next packet!
if(read_length < 0)
@@ -112,7 +115,7 @@ void AUD_FFMPEGReader::init()
for(unsigned int i = 0; i < m_formatCtx->nb_streams; i++)
{
if((m_formatCtx->streams[i]->codec->codec_type == CODEC_TYPE_AUDIO)
if((m_formatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO)
&& (m_stream < 0))
{
m_stream=i;

View File

@@ -39,19 +39,6 @@
#include <libswscale/swscale.h>
#include <libavcodec/opt.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
#else
#define FFMPEG_CODEC_IS_POINTER 1
#define FFMPEG_CODEC_TIME_BASE 1
#endif
#if LIBAVFORMAT_VERSION_INT >= (52 << 16)
#define OUTFILE_PB (outfile->pb)
#else
#define OUTFILE_PB (&outfile->pb)
#endif
#if defined(WIN32) && (!(defined snprintf))
#define snprintf _snprintf
#endif
@@ -114,24 +101,12 @@ static void delete_picture(AVFrame* f)
}
}
#ifdef FFMPEG_CODEC_IS_POINTER
static AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return stream->codec;
}
#else
static AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return &stream->codec;
}
#endif
static int write_audio_frame(void)
{
AVCodecContext* c = NULL;
AVPacket pkt;
c = get_codec_from_stream(audio_stream);
c = audio_stream->codec;
av_init_packet(&pkt);
pkt.size = 0;
@@ -153,17 +128,15 @@ static int write_audio_frame(void)
if(c->coded_frame && c->coded_frame->pts != AV_NOPTS_VALUE)
{
#ifdef FFMPEG_CODEC_TIME_BASE
pkt.pts = av_rescale_q(c->coded_frame->pts,
c->time_base, audio_stream->time_base);
#else
pkt.pts = c->coded_frame->pts;
#endif
c->time_base, audio_stream->time_base);
fprintf(stderr, "Audio Frame PTS: %d\n", (int)pkt.pts);
}
pkt.stream_index = audio_stream->index;
pkt.flags |= PKT_FLAG_KEY;
pkt.flags |= AV_PKT_FLAG_KEY;
if (av_interleaved_write_frame(outfile, &pkt) != 0) {
fprintf(stderr, "Error writing audio packet!\n");
return -1;
@@ -263,10 +236,10 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
{
int outsize = 0;
int ret, success= 1;
AVCodecContext* c = get_codec_from_stream(video_stream);
#ifdef FFMPEG_CODEC_TIME_BASE
AVCodecContext* c = video_stream->codec;
frame->pts = rd->cfra - rd->sfra;
#endif
if (rd->mode & R_FIELDS) {
frame->top_field_first = ((rd->mode & R_ODDFIELD) != 0);
}
@@ -278,19 +251,15 @@ static int write_video_frame(RenderData *rd, AVFrame* frame, ReportList *reports
av_init_packet(&packet);
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
#ifdef FFMPEG_CODEC_TIME_BASE
packet.pts = av_rescale_q(c->coded_frame->pts,
c->time_base,
video_stream->time_base);
#else
packet.pts = c->coded_frame->pts;
#endif
fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
} else {
fprintf(stderr, "Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame)
packet.flags |= PKT_FLAG_KEY;
packet.flags |= AV_PKT_FLAG_KEY;
packet.stream_index = video_stream->index;
packet.data = video_buffer;
packet.size = outsize;
@@ -312,7 +281,7 @@ static AVFrame* generate_video_frame(uint8_t* pixels, ReportList *reports)
{
uint8_t* rendered_frame;
AVCodecContext* c = get_codec_from_stream(video_stream);
AVCodecContext* c = video_stream->codec;
int width = c->width;
int height = c->height;
AVFrame* rgb_frame;
@@ -396,7 +365,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
switch(prop->type) {
case IDP_STRING:
fprintf(stderr, "%s.\n", IDP_String(prop));
rv = av_set_string(c, prop->name, IDP_String(prop));
av_set_string3(c, prop->name, IDP_String(prop), 1, &rv);
break;
case IDP_FLOAT:
fprintf(stderr, "%g.\n", IDP_Float(prop));
@@ -407,7 +376,7 @@ static void set_ffmpeg_property_option(AVCodecContext* c, IDProperty * prop)
if (param) {
if (IDP_Int(prop)) {
rv = av_set_string(c, name, param);
av_set_string3(c, name, param, 1, &rv);
} else {
return;
}
@@ -459,9 +428,9 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
/* Set up the codec context */
c = get_codec_from_stream(st);
c = st->codec;
c->codec_id = codec_id;
c->codec_type = CODEC_TYPE_VIDEO;
c->codec_type = AVMEDIA_TYPE_VIDEO;
/* Get some values from the current render settings */
@@ -469,7 +438,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->width = rectx;
c->height = recty;
#ifdef FFMPEG_CODEC_TIME_BASE
/* FIXME: Really bad hack (tm) for NTSC support */
if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
c->time_base.den = 2997;
@@ -482,20 +450,6 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->time_base.den = rd->frs_sec * 100000;
c->time_base.num = ((double) rd->frs_sec_base) * 100000;
}
#else
/* FIXME: Really bad hack (tm) for NTSC support */
if (ffmpeg_type == FFMPEG_DV && rd->frs_sec != 25) {
c->frame_rate = 2997;
c->frame_rate_base = 100;
} else if ((double) ((int) rd->frs_sec_base) ==
rd->frs_sec_base) {
c->frame_rate = rd->frs_sec;
c->frame_rate_base = rd->frs_sec_base;
} else {
c->frame_rate = rd->frs_sec * 100000;
c->frame_rate_base = ((double) rd->frs_sec_base)*100000;
}
#endif
c->gop_size = ffmpeg_gop_size;
c->bit_rate = ffmpeg_video_bitrate*1000;
@@ -519,7 +473,7 @@ static AVStream* alloc_video_stream(RenderData *rd, int codec_id, AVFormatContex
c->pix_fmt = PIX_FMT_YUV422P;
}
if (codec_id == CODEC_ID_XVID) {
if (ffmpeg_type == FFMPEG_XVID) {
/* arghhhh ... */
c->pix_fmt = PIX_FMT_YUV420P;
c->codec_tag = (('D'<<24) + ('I'<<16) + ('V'<<8) + 'X');
@@ -586,9 +540,9 @@ static AVStream* alloc_audio_stream(RenderData *rd, int codec_id, AVFormatContex
st = av_new_stream(of, 1);
if (!st) return NULL;
c = get_codec_from_stream(st);
c = st->codec;
c->codec_id = codec_id;
c->codec_type = CODEC_TYPE_AUDIO;
c->codec_type = AVMEDIA_TYPE_AUDIO;
c->sample_rate = rd->ffcodecdata.audio_mixrate;
c->bit_rate = ffmpeg_audio_bitrate*1000;
@@ -666,13 +620,13 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
BKE_report(reports, RPT_ERROR, "No valid formats found.");
return 0;
}
fmt = guess_format(NULL, exts[0], NULL);
fmt = av_guess_format(NULL, exts[0], NULL);
if (!fmt) {
BKE_report(reports, RPT_ERROR, "No valid formats found.");
return 0;
}
of = av_alloc_format_context();
of = avformat_alloc_context();
if (!of) {
BKE_report(reports, RPT_ERROR, "Error opening output file");
return 0;
@@ -713,7 +667,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
fmt->video_codec = CODEC_ID_H264;
break;
case FFMPEG_XVID:
fmt->video_codec = CODEC_ID_XVID;
fmt->video_codec = CODEC_ID_MPEG4;
break;
case FFMPEG_FLV:
fmt->video_codec = CODEC_ID_FLV1;
@@ -772,7 +726,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
return 0;
}
if (!(fmt->flags & AVFMT_NOFILE)) {
if (url_fopen(&of->pb, name, URL_WRONLY) < 0) {
if (avio_open(&of->pb, name, AVIO_FLAG_WRITE) < 0) {
BKE_report(reports, RPT_ERROR, "Could not open file for writing.");
return 0;
}
@@ -780,7 +734,7 @@ static int start_ffmpeg_impl(struct RenderData *rd, int rectx, int recty, Report
av_write_header(of);
outfile = of;
dump_format(of, 0, name, 1);
av_dump_format(of, 0, name, 1);
return 1;
}
@@ -807,7 +761,7 @@ void flush_ffmpeg(void)
int outsize = 0;
int ret = 0;
AVCodecContext* c = get_codec_from_stream(video_stream);
AVCodecContext* c = video_stream->codec;
/* get the delayed frames */
while (1) {
AVPacket packet;
@@ -822,19 +776,15 @@ void flush_ffmpeg(void)
break;
}
if (c->coded_frame->pts != AV_NOPTS_VALUE) {
#ifdef FFMPEG_CODEC_TIME_BASE
packet.pts = av_rescale_q(c->coded_frame->pts,
c->time_base,
video_stream->time_base);
#else
packet.pts = c->coded_frame->pts;
#endif
fprintf(stderr, "Video Frame PTS: %d\n", (int)packet.pts);
} else {
fprintf(stderr, "Video Frame PTS: not set\n");
}
if (c->coded_frame->key_frame) {
packet.flags |= PKT_FLAG_KEY;
packet.flags |= AV_PKT_FLAG_KEY;
}
packet.stream_index = video_stream->index;
packet.data = video_buffer;
@@ -845,7 +795,7 @@ void flush_ffmpeg(void)
break;
}
}
avcodec_flush_buffers(get_codec_from_stream(video_stream));
avcodec_flush_buffers(video_stream->codec);
}
/* **********************************************************************
@@ -902,7 +852,7 @@ int start_ffmpeg(struct Scene *scene, RenderData *rd, int rectx, int recty, Repo
if(audio_stream)
{
AVCodecContext* c = get_codec_from_stream(audio_stream);
AVCodecContext* c = audio_stream->codec;
AUD_DeviceSpecs specs;
specs.channels = c->channels;
specs.format = AUD_FORMAT_S16;
@@ -945,7 +895,7 @@ int append_ffmpeg(RenderData *rd, int frame, int *pixels, int rectx, int recty,
success= (avframe && write_video_frame(rd, avframe, reports));
if (ffmpeg_autosplit) {
if (url_ftell(OUTFILE_PB) > FFMPEG_AUTOSPLIT_SIZE) {
if (avio_tell(outfile->pb) > FFMPEG_AUTOSPLIT_SIZE) {
end_ffmpeg();
ffmpeg_autosplit_count++;
success &= start_ffmpeg_impl(rd, rectx, recty, reports);
@@ -974,7 +924,7 @@ void end_ffmpeg(void)
audio_mixdown_device = 0;
}
if (video_stream && get_codec_from_stream(video_stream)) {
if (video_stream && video_stream->codec) {
fprintf(stderr, "Flushing delayed frames...\n");
flush_ffmpeg ();
}
@@ -985,8 +935,8 @@ void end_ffmpeg(void)
/* Close the video codec */
if (video_stream && get_codec_from_stream(video_stream)) {
avcodec_close(get_codec_from_stream(video_stream));
if (video_stream && video_stream->codec) {
avcodec_close(video_stream->codec);
printf("zero video stream %p\n", video_stream);
video_stream = 0;
}
@@ -1007,7 +957,7 @@ void end_ffmpeg(void)
}
if (outfile && outfile->oformat) {
if (!(outfile->oformat->flags & AVFMT_NOFILE)) {
url_fclose(OUTFILE_PB);
avio_close(outfile->pb);
}
}
if (outfile) {
@@ -1101,12 +1051,12 @@ IDProperty *ffmpeg_property_add(RenderData *rd, char * type, int opt_index, int
switch (o->type) {
case FF_OPT_TYPE_INT:
case FF_OPT_TYPE_INT64:
val.i = o->default_val;
val.i = o->default_val.i64;
idp_type = IDP_INT;
break;
case FF_OPT_TYPE_DOUBLE:
case FF_OPT_TYPE_FLOAT:
val.f = o->default_val;
val.f = o->default_val.dbl;
idp_type = IDP_FLOAT;
break;
case FF_OPT_TYPE_STRING:
@@ -1314,7 +1264,7 @@ void ffmpeg_set_preset(RenderData *rd, int preset)
case FFMPEG_PRESET_XVID:
if(preset == FFMPEG_PRESET_XVID) {
rd->ffcodecdata.type = FFMPEG_AVI;
rd->ffcodecdata.codec = CODEC_ID_XVID;
rd->ffcodecdata.codec = CODEC_ID_MPEG4;
}
else if(preset == FFMPEG_PRESET_THEORA) {
rd->ffcodecdata.type = FFMPEG_OGG; // XXX broken
@@ -1357,7 +1307,7 @@ void ffmpeg_verify_image_type(RenderData *rd)
}
}
else if(rd->imtype == R_XVID) {
if(rd->ffcodecdata.codec != CODEC_ID_XVID) {
if(rd->ffcodecdata.codec != CODEC_ID_MPEG4) {
ffmpeg_set_preset(rd, FFMPEG_PRESET_XVID);
audio= 1;
}

View File

@@ -559,14 +559,14 @@ static int startffmpeg(struct anim * anim) {
return -1;
}
dump_format(pFormatCtx, 0, anim->name, 0);
av_dump_format(pFormatCtx, 0, anim->name, 0);
/* Find the first video stream */
videoStream=-1;
for(i=0; i<pFormatCtx->nb_streams; i++)
if(get_codec_from_stream(pFormatCtx->streams[i])->codec_type
== CODEC_TYPE_VIDEO) {
== AVMEDIA_TYPE_VIDEO) {
videoStream=i;
break;
}
@@ -830,10 +830,10 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
&& position - (anim->curposition + 1) < anim->preseek) {
while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
if (packet.stream_index == anim->videoStream) {
avcodec_decode_video(
avcodec_decode_video2(
anim->pCodecCtx,
anim->pFrame, &frameFinished,
packet.data, packet.size);
&packet);
if (frameFinished) {
anim->curposition++;
@@ -915,9 +915,9 @@ static ImBuf * ffmpeg_fetchibuf(struct anim * anim, int position) {
while(av_read_frame(anim->pFormatCtx, &packet)>=0) {
if(packet.stream_index == anim->videoStream) {
avcodec_decode_video(anim->pCodecCtx,
anim->pFrame, &frameFinished,
packet.data, packet.size);
avcodec_decode_video2(anim->pCodecCtx,
anim->pFrame, &frameFinished,
&packet);
if (seek_by_bytes && preseek_count > 0) {
preseek_count--;

View File

@@ -62,13 +62,6 @@
#include <libavformat/avformat.h>
#include <libavdevice/avdevice.h>
#include <libavutil/log.h>
#if LIBAVFORMAT_VERSION_INT < (49 << 16)
#define FFMPEG_OLD_FRAME_RATE 1
#else
#define FFMPEG_CODEC_IS_POINTER 1
#endif
#endif
#define UTIL_DEBUG 0
@@ -241,19 +234,6 @@ void do_init_ffmpeg(void)
}
}
#ifdef FFMPEG_CODEC_IS_POINTER
static AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return stream->codec;
}
#else
static AVCodecContext* get_codec_from_stream(AVStream* stream)
{
return &stream->codec;
}
#endif
static int isffmpeg (const char *filename) {
AVFormatContext *pFormatCtx;
unsigned int i;
@@ -284,15 +264,15 @@ static int isffmpeg (const char *filename) {
return 0;
}
if(UTIL_DEBUG) dump_format(pFormatCtx, 0, filename, 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] &&
get_codec_from_stream(pFormatCtx->streams[i]) &&
(get_codec_from_stream(pFormatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO))
pFormatCtx->streams[i]->codec &&
(pFormatCtx->streams[i]->codec->codec_type==AVMEDIA_TYPE_VIDEO))
{
videoStream=i;
break;
@@ -303,7 +283,7 @@ static int isffmpeg (const char *filename) {
return 0;
}
pCodecCtx = get_codec_from_stream(pFormatCtx->streams[videoStream]);
pCodecCtx = pFormatCtx->streams[videoStream]->codec;
/* Find the decoder for the video stream */
pCodec=avcodec_find_decoder(pCodecCtx->codec_id);

View File

@@ -2149,7 +2149,6 @@ static void rna_def_scene_render_data(BlenderRNA *brna)
{CODEC_ID_HUFFYUV, "HUFFYUV", 0, "HuffYUV", ""},
{CODEC_ID_DVVIDEO, "DV", 0, "DV", ""},
{CODEC_ID_H264, "H264", 0, "H.264", ""},
{CODEC_ID_XVID, "XVID", 0, "Xvid", ""},
{CODEC_ID_THEORA, "THEORA", 0, "Theora", ""},
{CODEC_ID_FLV1, "FLASH", 0, "Flash Video", ""},
{CODEC_ID_FFV1, "FFV1", 0, "FFmpeg video codec #1", ""},

View File

@@ -182,7 +182,7 @@ int VideoFFmpeg::openStream(const char *filename, AVInputFormat *inputFormat, AV
{
if(formatCtx->streams[i] &&
get_codec_from_stream(formatCtx->streams[i]) &&
(get_codec_from_stream(formatCtx->streams[i])->codec_type==CODEC_TYPE_VIDEO))
(get_codec_from_stream(formatCtx->streams[i])->codec_type==AVMEDIA_TYPE_VIDEO))
{
videoStream=i;
break;
@@ -368,9 +368,9 @@ void *VideoFFmpeg::cacheThread(void *data)
BLI_remlink(&video->m_packetCacheBase, cachePacket);
// use m_frame because when caching, it is not used in main thread
// we can't use currentFrame directly because we need to convert to RGB first
avcodec_decode_video(video->m_codecCtx,
avcodec_decode_video2(video->m_codecCtx,
video->m_frame, &frameFinished,
cachePacket->packet.data, cachePacket->packet.size);
&cachePacket->packet);
if(frameFinished)
{
AVFrame * input = video->m_frame;
@@ -641,7 +641,7 @@ void VideoFFmpeg::openCam (char * file, short camIdx)
if (m_captRate <= 0.f)
m_captRate = defFrameRate;
sprintf(rateStr, "%f", m_captRate);
av_parse_video_frame_rate(&frameRate, rateStr);
av_parse_video_rate(&frameRate, rateStr);
// populate format parameters
// need to specify the time base = inverse of rate
formatParams.time_base.num = frameRate.den;
@@ -924,10 +924,10 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
{
if (packet.stream_index == m_videoStream)
{
avcodec_decode_video(
avcodec_decode_video2(
m_codecCtx,
m_frame, &frameFinished,
packet.data, packet.size);
&packet);
if (frameFinished)
{
m_curPosition = (long)((packet.dts-startTs) * (m_baseFrameRate*timeBase) + 0.5);
@@ -999,9 +999,9 @@ AVFrame *VideoFFmpeg::grabFrame(long position)
{
if(packet.stream_index == m_videoStream)
{
avcodec_decode_video(m_codecCtx,
avcodec_decode_video2(m_codecCtx,
m_frame, &frameFinished,
packet.data, packet.size);
&packet);
// remember dts to compute exact frame number
dts = packet.dts;
if (frameFinished && !posFound)

View File

@@ -34,6 +34,7 @@ extern "C" {
#include <libavformat/avformat.h>
#include <libavcodec/avcodec.h>
#include <libavutil/rational.h>
#include <libavutil/parseutils.h>
#include <libswscale/swscale.h>
#include "DNA_listBase.h"
#include "BLI_threads.h"