[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [11560] branches/soc-2007-hcube/intern/ tinySND/ffmpeg: prepared for implementation
Csaba Hruska
csaba.hruska at gmail.com
Sun Aug 12 16:20:39 CEST 2007
Revision: 11560
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=11560
Author: hcube
Date: 2007-08-12 16:20:39 +0200 (Sun, 12 Aug 2007)
Log Message:
-----------
prepared for implementation
Modified Paths:
--------------
branches/soc-2007-hcube/intern/tinySND/ffmpeg/ffmpegProvider.cpp
branches/soc-2007-hcube/intern/tinySND/ffmpeg/ffmpegProvider.h
Modified: branches/soc-2007-hcube/intern/tinySND/ffmpeg/ffmpegProvider.cpp
===================================================================
--- branches/soc-2007-hcube/intern/tinySND/ffmpeg/ffmpegProvider.cpp 2007-08-12 14:18:12 UTC (rev 11559)
+++ branches/soc-2007-hcube/intern/tinySND/ffmpeg/ffmpegProvider.cpp 2007-08-12 14:20:39 UTC (rev 11560)
@@ -6,23 +6,468 @@
ffmpegProvider::ffmpegProvider( char *filename )
{
+ mIsFormatSupported = false;
+/*
+long sound_hdaudio_get_duration(struct hdaudio * hdaudio, int frame_rate)
+ return hdaudio->pFormatCtx->duration * frame_rate / AV_TIME_BASE;
+*/
+
+/*
+ struct hdaudio * rval;
+ int i, audioStream;
+
+ AVCodec *pCodec;
+ AVFormatContext *pFormatCtx;
+ AVCodecContext *pCodecCtx;
+
+ do_init_ffmpeg();
+
+ if(av_open_input_file(&pFormatCtx, filename, NULL, 0, NULL)!=0) {
+ return 0;
+ }
+
+ if(av_find_stream_info(pFormatCtx)<0) {
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+ dump_format(pFormatCtx, 0, filename, 0);
+
+
+ // Find the first audio stream
+ audioStream=-1;
+ for(i=0; i<pFormatCtx->nb_streams; i++)
+ if(get_codec_from_stream(pFormatCtx->streams[i])
+ ->codec_type == CODEC_TYPE_AUDIO)
+ {
+ audioStream=i;
+ break;
+ }
+
+ if(audioStream == -1) {
+ av_close_input_file(pFormatCtx);
+ return 0;
+ }
+
+ pCodecCtx = get_codec_from_stream(pFormatCtx->streams[audioStream]);
+
+ // Find the decoder for the audio 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;
+ }
+
+ rval = (struct hdaudio *)MEM_mallocN(sizeof(struct hdaudio),
+ "hdaudio struct");
+
+ rval->filename = strdup(filename);
+ rval->sample_rate = pCodecCtx->sample_rate;
+ rval->channels = pCodecCtx->channels;
+
+ rval->pFormatCtx = pFormatCtx;
+ rval->pCodecCtx = pCodecCtx;
+ rval->pCodec = pCodec;
+ rval->audioStream = audioStream;
+ rval->frame_position = -10;
+
+ rval->frame_duration = AV_TIME_BASE / 10;
+ rval->frame_alloc_duration = AV_TIME_BASE;
+ rval->decode_cache_size =
+ (long long) rval->sample_rate * rval->channels
+ * rval->frame_alloc_duration / AV_TIME_BASE
+ * 2;
+
+ rval->decode_cache = (short*) MEM_mallocN(
+ rval->decode_cache_size * sizeof(short)
+ + AVCODEC_MAX_AUDIO_FRAME_SIZE,
+ "hdaudio decode cache");
+ rval->decode_cache_zero = rval->decode_cache;
+ rval->decode_pos = 0;
+ rval->target_channels = -1;
+ rval->target_rate = -1;
+ rval->resampler = 0;
+ rval->resample_cache = 0;
+ rval->resample_samples_written = 0;
+ rval->resample_samples_in = 0;
+ return rval;
+*/
+ mIsFormatSupported = true;
}
ffmpegProvider::~ffmpegProvider(void)
{
+/*
+ if (hdaudio) {
+ avcodec_close(hdaudio->pCodecCtx);
+ av_close_input_file(hdaudio->pFormatCtx);
+ MEM_freeN (hdaudio->decode_cache);
+ if (hdaudio->resample_cache) {
+ MEM_freeN(hdaudio->resample_cache);
+ }
+ free(hdaudio->filename);
+ MEM_freeN (hdaudio);
+ }
+*/
}
bool ffmpegProvider::isFormatSupported(void)
{
- return false;
+ return mIsFormatSupported;
}
void ffmpegProvider::seek( int frameNum )
{
}
-int ffmpegProvider::fillBuffer( float *buffer, int channelIndex, int framesNum )
+int ffmpegProvider::fillBuffer( float *buffer, int framesNum )
{
return 0;
}
+/*
+static void sound_hdaudio_extract_small_block(
+ struct hdaudio * hdaudio,
+ short * target_buffer,
+ int sample_position, // units of target_rate
+ int target_rate,
+ int target_channels,
+ int nb_samples )// in target
+{
+ AVPacket packet;
+ int frame_position;
+ int frame_size = (long long) target_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+ int in_frame_size = (long long) hdaudio->sample_rate
+ * hdaudio->frame_duration / AV_TIME_BASE;
+ int rate_conversion =
+ (target_rate != hdaudio->sample_rate)
+ || (target_channels != hdaudio->channels);
+ int sample_ofs = target_channels * (sample_position % frame_size);
+ frame_position = sample_position / frame_size;
+
+ if (hdaudio == 0) return;
+
+ if (rate_conversion) {
+ if (hdaudio->resampler &&
+ (hdaudio->target_rate != target_rate
+ || hdaudio->target_channels != target_channels)) {
+ audio_resample_close(hdaudio->resampler);
+ hdaudio->resampler = 0;
+ }
+ if (!hdaudio->resampler) {
+ hdaudio->resampler = audio_resample_init(
+ target_channels, hdaudio->channels,
+ target_rate, hdaudio->sample_rate);
+ hdaudio->target_rate = target_rate;
+ hdaudio->target_channels = target_channels;
+ if (hdaudio->resample_cache) {
+ MEM_freeN(hdaudio->resample_cache);
+ }
+
+
+ hdaudio->resample_cache = (short*) MEM_mallocN(
+ (long long)
+ hdaudio->target_channels
+ * frame_size * 2
+ * sizeof(short),
+ "hdaudio resample cache");
+ if (frame_position == hdaudio->frame_position) {
+ hdaudio->resample_samples_in =
+ in_frame_size * 7 / 4;
+ hdaudio->resample_samples_written
+ = audio_resample(
+ hdaudio->resampler,
+ hdaudio->resample_cache,
+ hdaudio->decode_cache_zero,
+ in_frame_size * 7 / 4);
+ }
+ }
+ }
+
+ if (frame_position == hdaudio->frame_position + 1
+ && in_frame_size * hdaudio->channels <= hdaudio->decode_pos) {
+ int bl_size = in_frame_size * hdaudio->channels;
+ int decode_pos = hdaudio->decode_pos;
+
+ hdaudio->frame_position = frame_position;
+
+ memmove(hdaudio->decode_cache,
+ hdaudio->decode_cache + bl_size,
+ (decode_pos - bl_size) * sizeof(short));
+
+ decode_pos -= bl_size;
+
+ memset(hdaudio->decode_cache + decode_pos, 0,
+ (hdaudio->decode_cache_size - decode_pos)
+ * sizeof(short));
+
+
+ while(av_read_frame(hdaudio->pFormatCtx, &packet) >= 0) {
+ int data_size;
+ int len;
+ uint8_t *audio_pkt_data;
+ int audio_pkt_size;
+
+ if(packet.stream_index != hdaudio->audioStream) {
+ av_free_packet(&packet);
+ continue;
+ }
+
+ audio_pkt_data = packet.data;
+ audio_pkt_size = packet.size;
+
+ while (audio_pkt_size > 0) {
+ len = avcodec_decode_audio(
+ hdaudio->pCodecCtx,
+ hdaudio->decode_cache
+ + decode_pos,
+ &data_size,
+ audio_pkt_data,
+ audio_pkt_size);
+ if (len <= 0) {
+ audio_pkt_size = 0;
+ break;
+ }
+
+ audio_pkt_size -= len;
+ audio_pkt_data += len;
+
+ if (data_size <= 0) {
+ continue;
+ }
+
+ decode_pos += data_size / sizeof(short);
+ if (decode_pos + data_size
+ / sizeof(short)
+ > hdaudio->decode_cache_size) {
+ break;
+ }
+ }
+ av_free_packet(&packet);
+
+ if (decode_pos + data_size / sizeof(short)
+ > hdaudio->decode_cache_size) {
+ break;
+ }
+ }
+
+ if (rate_conversion) {
+ int written = hdaudio->resample_samples_written
+ * target_channels;
+ int ofs = target_channels * frame_size;
+ int recycle = written - ofs;
+ int next_in = in_frame_size
+ + (3.0/4.0
+ - (double) recycle / (double)
+ (frame_size * target_channels)
+ ) * in_frame_size;
+
+ memmove(hdaudio->resample_cache,
+ hdaudio->resample_cache + ofs,
+ recycle * sizeof(short));
+
+ hdaudio->resample_samples_written
+ = audio_resample(
+ hdaudio->resampler,
+ hdaudio->resample_cache + recycle,
+ hdaudio->decode_cache_zero
+ + hdaudio->resample_samples_in
+ * hdaudio->channels
+ - bl_size,
+ next_in)
+ + recycle / target_channels;
+
+ hdaudio->resample_samples_in = next_in;
+ }
+
+ hdaudio->decode_pos = decode_pos;
+ }
+
+ if (frame_position != hdaudio->frame_position) {
+ long decode_pos = 0;
+ long long st_time = hdaudio->pFormatCtx
+ ->streams[hdaudio->audioStream]->start_time;
+ double time_base =
+ av_q2d(hdaudio->pFormatCtx
+ ->streams[hdaudio->audioStream]->time_base);
+ long long pos = (long long) frame_position * AV_TIME_BASE
+ * hdaudio->frame_duration / AV_TIME_BASE;
+
+ long long seek_pos;
+
+ hdaudio->frame_position = frame_position;
+
+ if (st_time == AV_NOPTS_VALUE) {
+ st_time = 0;
+ }
+
+ pos += st_time * AV_TIME_BASE * time_base;
+
+ // seek a little bit before the target position,
+ // (ffmpeg seek algorithm doesn't seem to work always as
+ // specified...)
+
+
+ seek_pos = pos - (AV_TIME_BASE
+ * hdaudio->frame_duration
+ / AV_TIME_BASE / 10);
+ if (seek_pos < 0) {
+ seek_pos = pos;
+ }
+
+ av_seek_frame(hdaudio->pFormatCtx, -1,
+ seek_pos,
+ AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD);
+ avcodec_flush_buffers(hdaudio->pCodecCtx);
+
+ memset(hdaudio->decode_cache, 0,
+ hdaudio->decode_cache_size * sizeof(short));
+
+ hdaudio->decode_cache_zero = hdaudio->decode_cache;
+
+ while(av_read_frame(hdaudio->pFormatCtx, &packet) >= 0) {
+ int data_size;
+ int len;
+ uint8_t *audio_pkt_data;
+ int audio_pkt_size;
+
+ if(packet.stream_index != hdaudio->audioStream) {
+ av_free_packet(&packet);
+ continue;
+ }
+
+ audio_pkt_data = packet.data;
+ audio_pkt_size = packet.size;
+
+ if (!hdaudio->decode_cache_zero
+ && audio_pkt_size > 0) {
+ long long diff;
+
+ if (packet.pts == AV_NOPTS_VALUE) {
+ fprintf(stderr,
+ "hdaudio: audio "
+ "pts=NULL audio "
+ "distortion!\n");
+ diff = 0;
+ } else {
+ long long pts = packet.pts;
+ long long spts = (long long) (
+ pos / time_base / AV_TIME_BASE
+ + 0.5);
+ diff = spts - pts;
+ if (diff < 0) {
+ fprintf(stderr,
+ "hdaudio: "
+ "negative seek: "
+ "%lld < %lld "
+ "(pos=%lld) "
+ "audio distortion!!\n",
+ spts, pts, pos);
+ diff = 0;
+ }
+ }
+
+
+ diff *= hdaudio->sample_rate * time_base;
+ diff *= hdaudio->channels;
+
+ if (diff > hdaudio->decode_cache_size / 2) {
+ fprintf(stderr,
+ "hdaudio: audio "
+ "diff too large!!\n");
+ diff = 0;
+ }
+
+ hdaudio->decode_cache_zero
+ = hdaudio->decode_cache + diff;
+ }
+
+ while (audio_pkt_size > 0) {
+ len = avcodec_decode_audio(
+ hdaudio->pCodecCtx,
+ hdaudio->decode_cache
+ + decode_pos,
+ &data_size,
+ audio_pkt_data,
+ audio_pkt_size);
+ if (len <= 0) {
+ audio_pkt_size = 0;
+ break;
+ }
+
+ audio_pkt_size -= len;
+ audio_pkt_data += len;
+
+ if (data_size <= 0) {
+ continue;
+ }
+
+ decode_pos += data_size / sizeof(short);
+ if (decode_pos + data_size
+ / sizeof(short)
+ > hdaudio->decode_cache_size) {
+ break;
+ }
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list