switched ffmpeg files back to v0.2.1
This commit is contained in:
1 parent
c7be612b9a
commit
10df73b535
20 files changed
+317
-438
No files matched your search
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -11,6 +11,10 @@ namespace Vocaluxe.Lib.Sound.Decoder
|
||||
{
|
||||
class CAudioDecoderFFmpeg: CAudioDecoder
|
||||
{
|
||||
private TAc_read_callback _rc;
|
||||
private TAc_seek_callback _sc;
|
||||
private FileStream _fs;
|
||||
|
||||
private IntPtr _instance = IntPtr.Zero;
|
||||
private IntPtr _audiodecoder = IntPtr.Zero;
|
||||
|
||||
@@ -23,7 +27,11 @@ namespace Vocaluxe.Lib.Sound.Decoder
|
||||
|
||||
public override void Init()
|
||||
{
|
||||
_rc = new TAc_read_callback(read_proc);
|
||||
_sc = new TAc_seek_callback(seek_proc);
|
||||
|
||||
_FileOpened = false;
|
||||
|
||||
_Initialized = true;
|
||||
}
|
||||
|
||||
@@ -33,49 +41,63 @@ namespace Vocaluxe.Lib.Sound.Decoder
|
||||
return;
|
||||
|
||||
_FileName = FileName;
|
||||
_instance = CAcinerella.ac_init();
|
||||
_fs = new FileStream(FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
int ret = 0;
|
||||
if ((ret = CAcinerella.ac_open2(_instance, _FileName)) < 0)
|
||||
{
|
||||
CLog.LogError("Error opening sound file (Errorcode: " + ret.ToString() + "): " + _FileName);
|
||||
return;
|
||||
}
|
||||
_instance = CAcinerella.ac_init();
|
||||
CAcinerella.ac_open(_instance, IntPtr.Zero, null, _rc, _sc, null, IntPtr.Zero);
|
||||
|
||||
_Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance));
|
||||
|
||||
if (!_Instance.opened || _Instance.info.duration == 0)
|
||||
if (!_Instance.opened)
|
||||
{
|
||||
if (!_Instance.opened)
|
||||
CLog.LogError("Can't open sound file: " + _FileName);
|
||||
else
|
||||
CLog.LogError("Can't open sound file (length = 0?): " + _FileName);
|
||||
//Free();
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
int AudioStreamIndex = -1;
|
||||
|
||||
TAc_stream_info Info = new TAc_stream_info();
|
||||
for (int i = 0; i < _Instance.stream_count; i++)
|
||||
{
|
||||
_audiodecoder = CAcinerella.ac_create_audio_decoder(_instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("Can't create audio decoder for file: " + _FileName + "; " + e.Message);
|
||||
return;
|
||||
CAcinerella.ac_get_stream_info(_instance, i, out Info);
|
||||
|
||||
if (Info.stream_type == TAc_stream_type.AC_STREAM_TYPE_AUDIO)
|
||||
{
|
||||
try
|
||||
{
|
||||
_audiodecoder = CAcinerella.ac_create_decoder(_instance, i);
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
AudioStreamIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (_audiodecoder == IntPtr.Zero)
|
||||
if (AudioStreamIndex < 0)
|
||||
{
|
||||
CLog.LogError("Can't create audio decoder for file: " + _FileName);
|
||||
//Free();
|
||||
return;
|
||||
}
|
||||
|
||||
TAc_decoder Audiodecoder = (TAc_decoder)Marshal.PtrToStructure(_audiodecoder, typeof(TAc_decoder));
|
||||
|
||||
_FormatInfo = new FormatInfo();
|
||||
|
||||
_FormatInfo.SamplesPerSecond = Audiodecoder.stream_info.audio_info.samples_per_second;
|
||||
_FormatInfo.BitDepth = Audiodecoder.stream_info.audio_info.bit_depth;
|
||||
_FormatInfo.ChannelCount = Audiodecoder.stream_info.audio_info.channel_count;
|
||||
|
||||
_CurrentTime = 0f;
|
||||
|
||||
if (_FormatInfo.BitDepth != 16)
|
||||
{
|
||||
CLog.LogError("Unsupported BitDepth in file " + FileName);
|
||||
return;
|
||||
}
|
||||
_FileOpened = true;
|
||||
}
|
||||
|
||||
@@ -179,5 +201,23 @@ namespace Vocaluxe.Lib.Sound.Decoder
|
||||
Buffer = null;
|
||||
TimeStamp = 0f;
|
||||
}
|
||||
|
||||
#region Callbacks
|
||||
private Int32 read_proc(IntPtr sender, IntPtr buf, Int32 size)
|
||||
{
|
||||
Int32 r = 0;
|
||||
|
||||
byte[] bb = new byte[size];
|
||||
r = _fs.Read(bb, 0, size);
|
||||
Marshal.Copy(bb, 0, buf, size);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private Int64 seek_proc(IntPtr sender, Int64 pos, Int32 whence)
|
||||
{
|
||||
return (Int64)_fs.Seek((long)pos, (SeekOrigin)whence);
|
||||
}
|
||||
#endregion Callbacks
|
||||
}
|
||||
}
|
||||
@@ -253,17 +253,6 @@ namespace Vocaluxe.Lib.Video.Acinerella
|
||||
return _ac_open(PAc_instance, sender, open_proc, read_proc, seek_proc, close_proc, proberesult);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(AcDll, EntryPoint = "ac_open2", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
|
||||
private static extern Int32 _ac_open2(IntPtr PAc_instance, [MarshalAs(UnmanagedType.LPStr)]string Filename);
|
||||
|
||||
public static Int32 ac_open2(IntPtr PAc_instance, string Filename)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _ac_open2(PAc_instance, Filename);
|
||||
}
|
||||
}
|
||||
|
||||
// Closes an opened media file.
|
||||
//procedure ac_close(inst: PAc_instance);cdecl; external ac_dll;
|
||||
@@ -327,28 +316,6 @@ namespace Vocaluxe.Lib.Video.Acinerella
|
||||
return _ac_create_decoder(PAc_instance, nb);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(AcDll, EntryPoint = "ac_create_audio_decoder", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr _ac_create_audio_decoder(IntPtr PAc_instance);
|
||||
|
||||
public static IntPtr ac_create_audio_decoder(IntPtr PAc_instance)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _ac_create_audio_decoder(PAc_instance);
|
||||
}
|
||||
}
|
||||
|
||||
[DllImport(AcDll, EntryPoint = "ac_create_video_decoder", ExactSpelling = false, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Auto)]
|
||||
private static extern IntPtr _ac_create_video_decoder(IntPtr PAc_instance);
|
||||
|
||||
public static IntPtr ac_create_video_decoder(IntPtr PAc_instance)
|
||||
{
|
||||
lock (_lock)
|
||||
{
|
||||
return _ac_create_video_decoder(PAc_instance);
|
||||
}
|
||||
}
|
||||
|
||||
// Frees an created decoder.
|
||||
//procedure ac_free_decoder(pDecoder: PAc_decoder); cdecl; external ac_dll;
|
||||
|
||||
@@ -23,7 +23,6 @@
|
||||
#include <libavcodec/avcodec.h>
|
||||
#include <libavutil/avutil.h>
|
||||
#include <libswscale/swscale.h>
|
||||
#include <libswresample/swresample.h>
|
||||
#include <string.h>
|
||||
|
||||
#define AUDIO_BUFFER_BASE_SIZE AVCODEC_MAX_AUDIO_FRAME_SIZE
|
||||
@@ -81,8 +80,8 @@ struct _ac_audio_decoder {
|
||||
ac_decoder decoder;
|
||||
int sought;
|
||||
double last_timecode;
|
||||
//uint8_t *tmp_data;
|
||||
//int tmp_data_length;
|
||||
uint8_t *tmp_data;
|
||||
int tmp_data_length;
|
||||
int max_buffer_size;
|
||||
AVCodec *pCodec;
|
||||
AVCodecContext *pCodecCtx;
|
||||
@@ -205,7 +204,7 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(
|
||||
return (lp_ac_proberesult)fmt;
|
||||
}
|
||||
|
||||
#define PROBE_BUF_MIN 1024
|
||||
#define PROBE_BUF_MIN 2048
|
||||
#define PROBE_BUF_MAX (1<<20)
|
||||
|
||||
|
||||
@@ -339,7 +338,7 @@ int CALL_CONVT ac_open(
|
||||
//Retrieve stream information
|
||||
AVFormatContext *ctx = ((lp_ac_data)pacInstance)->pFormatCtx;
|
||||
if(avformat_find_stream_info(ctx, NULL) >= 0) {
|
||||
pacInstance->info.duration = ctx->duration * 1000 / AV_TIME_BASE;
|
||||
pacInstance->info.duration = ctx->duration * 1000 / AV_TIME_BASE;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
@@ -351,39 +350,6 @@ int CALL_CONVT ac_open(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CALL_CONVT ac_open2(lp_ac_instance pacInstance, const char* filename)
|
||||
{
|
||||
pacInstance->opened = 0;
|
||||
|
||||
//Store the given parameters in the ac Instance
|
||||
((lp_ac_data)pacInstance)->sender = NULL;
|
||||
((lp_ac_data)pacInstance)->open_proc = NULL;
|
||||
((lp_ac_data)pacInstance)->read_proc = NULL;
|
||||
((lp_ac_data)pacInstance)->seek_proc = NULL;
|
||||
((lp_ac_data)pacInstance)->close_proc = NULL;
|
||||
|
||||
/* open input file, and allocate format context */
|
||||
int ret = 0;
|
||||
if ((ret = avformat_open_input(&((lp_ac_data)pacInstance)->pFormatCtx, filename, NULL, NULL)) < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* retrieve stream information */
|
||||
if ((ret = avformat_find_stream_info(((lp_ac_data)pacInstance)->pFormatCtx, NULL)) < 0)
|
||||
{
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
pacInstance->info.duration = ((lp_ac_data)pacInstance)->pFormatCtx->duration * 1000 / AV_TIME_BASE;
|
||||
|
||||
//Set some information in the instance variable
|
||||
pacInstance->stream_count = ((lp_ac_data)pacInstance)->pFormatCtx->nb_streams;
|
||||
pacInstance->opened = pacInstance->stream_count > 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void CALL_CONVT ac_close(lp_ac_instance pacInstance) {
|
||||
if (pacInstance->opened) {
|
||||
//Close the opened file
|
||||
@@ -438,13 +404,42 @@ void CALL_CONVT ac_get_stream_info(lp_ac_instance pacInstance, int nb, lp_ac_str
|
||||
info->stream_type = AC_STREAM_TYPE_AUDIO;
|
||||
|
||||
//Store more information about the video stream
|
||||
info->audio_info.samples_per_second =
|
||||
info->audio_info.samples_per_second =
|
||||
((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->sample_rate;
|
||||
info->audio_info.channel_count = 2;
|
||||
//((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->channels;
|
||||
|
||||
// Set bit depth (its always 16Bit because of the conversion!
|
||||
info->audio_info.bit_depth = 16;
|
||||
info->audio_info.channel_count =
|
||||
((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->channels;
|
||||
|
||||
// Set bit depth
|
||||
switch (((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec->sample_fmt) {
|
||||
//8-Bit
|
||||
case AV_SAMPLE_FMT_U8:
|
||||
info->audio_info.bit_depth =
|
||||
8;
|
||||
break;
|
||||
|
||||
//16-Bit
|
||||
case AV_SAMPLE_FMT_S16:
|
||||
info->audio_info.bit_depth =
|
||||
16;
|
||||
break;
|
||||
|
||||
/* //24-Bit (removed in the newest ffmpeg version)
|
||||
case SAMPLE_FMT_S24:
|
||||
info->additional_info.audio_info.bit_depth =
|
||||
24;
|
||||
break; */
|
||||
|
||||
//32-Bit
|
||||
case AV_SAMPLE_FMT_S32: case AV_SAMPLE_FMT_FLT:
|
||||
info->audio_info.bit_depth =
|
||||
32;
|
||||
break;
|
||||
|
||||
//Unknown format, return zero
|
||||
default:
|
||||
info->audio_info.bit_depth =
|
||||
0;
|
||||
}
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -506,189 +501,89 @@ enum PixelFormat convert_pix_format(ac_output_format fmt) {
|
||||
}
|
||||
|
||||
//Init a video decoder
|
||||
void* _ac_create_video_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) {
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_video_decoder pDecoder;
|
||||
pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_video_decoder));
|
||||
void* ac_create_video_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) {
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_video_decoder pDecoder;
|
||||
pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_video_decoder));
|
||||
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->pCodecCtx = ((lp_ac_data)(pacInstance))->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->decoder.stream_info = *info;
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id))) {
|
||||
return NULL; //Codec could not have been found
|
||||
}
|
||||
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->decoder.stream_info = *info;
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id)))
|
||||
return NULL; //Codec could not have been found
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
|
||||
//Open codec
|
||||
if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0)
|
||||
return NULL; //Codec could not have been opened
|
||||
//Open codec
|
||||
if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0) {
|
||||
return NULL; //Codec could not have been opened
|
||||
}
|
||||
|
||||
//Reserve frame variables
|
||||
pDecoder->pFrame = avcodec_alloc_frame();
|
||||
pDecoder->pFrameRGB = avcodec_alloc_frame();
|
||||
|
||||
pDecoder->pSwsCtx = NULL;
|
||||
|
||||
//Reserve buffer memory
|
||||
pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size);
|
||||
|
||||
//Reserve frame variables
|
||||
pDecoder->pFrame = avcodec_alloc_frame();
|
||||
pDecoder->pFrameRGB = avcodec_alloc_frame();
|
||||
|
||||
pDecoder->pSwsCtx = NULL;
|
||||
|
||||
//Reserve buffer memory
|
||||
pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size);
|
||||
|
||||
//Link decoder to buffer
|
||||
avpicture_fill(
|
||||
(AVPicture*)(pDecoder->pFrameRGB),
|
||||
pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
|
||||
return (void*)pDecoder;
|
||||
//Link decoder to buffer
|
||||
avpicture_fill(
|
||||
(AVPicture*)(pDecoder->pFrameRGB),
|
||||
pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
|
||||
return (void*)pDecoder;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//Init a audio decoder
|
||||
void* _ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) {
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_audio_decoder pDecoder;
|
||||
pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_audio_decoder));
|
||||
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->decoder.stream_info = *info;
|
||||
pDecoder->decoder.video_clock = 0;
|
||||
|
||||
//Temporary store codec context pointer
|
||||
AVCodecContext *pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->pCodecCtx = pCodecCtx;
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id)))
|
||||
return NULL;
|
||||
|
||||
//Open codec
|
||||
if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
//Initialize the buffers
|
||||
pDecoder->decoder.pBuffer = av_malloc(AUDIO_BUFFER_BASE_SIZE);
|
||||
pDecoder->decoder.buffer_size = 0;
|
||||
pDecoder->max_buffer_size = AUDIO_BUFFER_BASE_SIZE;
|
||||
|
||||
//pDecoder->tmp_data = NULL;
|
||||
//pDecoder->tmp_data_length = 0;
|
||||
|
||||
return (void*)pDecoder;
|
||||
}
|
||||
|
||||
lp_ac_decoder CALL_CONVT ac_create_video_decoder(lp_ac_instance pacInstance) {
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_video_decoder pDecoder;
|
||||
pDecoder = (lp_ac_video_decoder)(av_malloc(sizeof(ac_video_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_video_decoder));
|
||||
|
||||
int nb = av_find_best_stream(((lp_ac_data)pacInstance)->pFormatCtx, AVMEDIA_TYPE_VIDEO, -1, -1, NULL, 0);
|
||||
if (nb < 0)
|
||||
return NULL;
|
||||
|
||||
ac_stream_info info;
|
||||
ac_get_stream_info(pacInstance, nb, &info);
|
||||
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_VIDEO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->decoder.video_clock = 0;
|
||||
((lp_ac_decoder_data)pDecoder)->last_timecode = 0;
|
||||
((lp_ac_decoder_data)pDecoder)->sought = 1;
|
||||
pDecoder->pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->decoder.stream_info = info;
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pDecoder->pCodecCtx->codec_id)))
|
||||
return NULL; //Codec could not have been found
|
||||
|
||||
//Open codec
|
||||
if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0)
|
||||
return NULL; //Codec could not have been opened
|
||||
|
||||
//Reserve frame variables
|
||||
pDecoder->pFrame = avcodec_alloc_frame();
|
||||
pDecoder->pFrameRGB = avcodec_alloc_frame();
|
||||
|
||||
pDecoder->pSwsCtx = NULL;
|
||||
|
||||
//Reserve buffer memory
|
||||
pDecoder->decoder.buffer_size = avpicture_get_size(convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
pDecoder->decoder.pBuffer = (uint8_t*)av_malloc(pDecoder->decoder.buffer_size);
|
||||
|
||||
//Link decoder to buffer
|
||||
avpicture_fill(
|
||||
(AVPicture*)(pDecoder->pFrameRGB),
|
||||
pDecoder->decoder.pBuffer, convert_pix_format(pacInstance->output_format),
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height);
|
||||
|
||||
return (void*)pDecoder;
|
||||
}
|
||||
|
||||
lp_ac_decoder CALL_CONVT ac_create_audio_decoder(lp_ac_instance pacInstance)
|
||||
{
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_audio_decoder pDecoder;
|
||||
pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_audio_decoder));
|
||||
|
||||
int nb = av_find_best_stream(((lp_ac_data)pacInstance)->pFormatCtx, AVMEDIA_TYPE_AUDIO, -1, -1, NULL, 0);
|
||||
if (nb < 0)
|
||||
return NULL;
|
||||
|
||||
ac_stream_info info;
|
||||
ac_get_stream_info(pacInstance, nb, &info);
|
||||
void* ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info, int nb) {
|
||||
//Allocate memory for a new decoder instance
|
||||
lp_ac_audio_decoder pDecoder;
|
||||
pDecoder = (lp_ac_audio_decoder)(av_malloc(sizeof(ac_audio_decoder)));
|
||||
memset(pDecoder, 0, sizeof(ac_audio_decoder));
|
||||
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->decoder.stream_info = info;
|
||||
pDecoder->decoder.video_clock = 0;
|
||||
((lp_ac_decoder_data)pDecoder)->last_timecode = 0;
|
||||
((lp_ac_decoder_data)pDecoder)->sought = 1;
|
||||
|
||||
//Temporary store codec context pointer
|
||||
AVCodecContext *pCodecCtx = ((lp_ac_data)pacInstance)->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->pCodecCtx = pCodecCtx;
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id)))
|
||||
return NULL;
|
||||
//Set a few properties
|
||||
pDecoder->decoder.pacInstance = pacInstance;
|
||||
pDecoder->decoder.type = AC_DECODER_TYPE_AUDIO;
|
||||
pDecoder->decoder.stream_index = nb;
|
||||
pDecoder->decoder.stream_info = *info;
|
||||
pDecoder->decoder.video_clock = 0;
|
||||
|
||||
//Temporary store codec context pointer
|
||||
AVCodecContext *pCodecCtx = ((lp_ac_data)(pacInstance))->pFormatCtx->streams[nb]->codec;
|
||||
pDecoder->pCodecCtx = pCodecCtx;
|
||||
|
||||
//Find correspondenting codec
|
||||
if (!(pDecoder->pCodec = avcodec_find_decoder(pCodecCtx->codec_id))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Open codec
|
||||
if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
//Open codec
|
||||
if (avcodec_open2(pCodecCtx, pDecoder->pCodec, NULL) < 0)
|
||||
return NULL;
|
||||
|
||||
//Initialize the buffers
|
||||
pDecoder->decoder.pBuffer = av_malloc(AUDIO_BUFFER_BASE_SIZE);
|
||||
pDecoder->decoder.buffer_size = 0;
|
||||
pDecoder->max_buffer_size = AUDIO_BUFFER_BASE_SIZE;
|
||||
|
||||
//pDecoder->tmp_data = NULL;
|
||||
//pDecoder->tmp_data_length = 0;
|
||||
|
||||
return (void*)pDecoder;
|
||||
//Initialize the buffers
|
||||
pDecoder->decoder.pBuffer = NULL; //av_malloc(AUDIO_BUFFER_BASE_SIZE);
|
||||
pDecoder->decoder.buffer_size = 0;
|
||||
pDecoder->max_buffer_size = 0;
|
||||
|
||||
pDecoder->tmp_data = NULL;
|
||||
pDecoder->tmp_data_length = 0;
|
||||
|
||||
return (void*)pDecoder;
|
||||
}
|
||||
|
||||
lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb) {
|
||||
@@ -700,15 +595,12 @@ lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb) {
|
||||
lp_ac_decoder result;
|
||||
|
||||
if (info.stream_type == AC_STREAM_TYPE_VIDEO) {
|
||||
result = _ac_create_video_decoder(pacInstance, &info, nb);
|
||||
result = ac_create_video_decoder(pacInstance, &info, nb);
|
||||
}
|
||||
else if (info.stream_type == AC_STREAM_TYPE_AUDIO) {
|
||||
result = _ac_create_audio_decoder(pacInstance, &info, nb);
|
||||
result = ac_create_audio_decoder(pacInstance, &info, nb);
|
||||
}
|
||||
|
||||
if (result == NULL)
|
||||
return NULL;
|
||||
|
||||
((lp_ac_decoder_data)result)->last_timecode = 0;
|
||||
((lp_ac_decoder_data)result)->sought = 1;
|
||||
result->video_clock = 0;
|
||||
@@ -751,7 +643,13 @@ int ac_decode_video_package(lp_ac_package pPackage, lp_ac_video_decoder pDecoder
|
||||
pkt_tmp.size -= len;
|
||||
pkt_tmp.data += len;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
avcodec_decode_video2(
|
||||
pDecoder->pCodecCtx, pDecoder->pFrame, &finished,
|
||||
&(((lp_ac_package_data)pPackage)->ffpackage));
|
||||
*/
|
||||
|
||||
if (finished != 0) {
|
||||
pDecoder->pSwsCtx = sws_getCachedContext(pDecoder->pSwsCtx,
|
||||
pDecoder->pCodecCtx->width, pDecoder->pCodecCtx->height, pDecoder->pCodecCtx->pix_fmt,
|
||||
@@ -789,18 +687,6 @@ int ac_decode_video_package(lp_ac_package pPackage, lp_ac_video_decoder pDecoder
|
||||
return 0;
|
||||
}
|
||||
|
||||
int alloc_samples_array_and_data(uint8_t ***data, int *linesize, int nb_channels,
|
||||
int nb_samples, enum AVSampleFormat sample_fmt, int align)
|
||||
{
|
||||
int nb_planes = av_sample_fmt_is_planar(sample_fmt) ? nb_channels : 1;
|
||||
|
||||
*data = av_malloc(sizeof(*data) * nb_planes);
|
||||
if (!*data)
|
||||
return AVERROR(ENOMEM);
|
||||
return av_samples_alloc(*data, linesize, nb_channels,
|
||||
nb_samples, sample_fmt, align);
|
||||
}
|
||||
|
||||
int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder, lp_ac_decoder pDec) {
|
||||
double pts;
|
||||
//Variables describing the destination buffer
|
||||
@@ -808,18 +694,17 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder
|
||||
|
||||
//Make a copy of the package read by avformat, so that we can move the data pointers around
|
||||
AVPacket pkt_tmp = ((lp_ac_package_data)pPackage)->ffpackage;
|
||||
|
||||
|
||||
AVFrame *decoded_frame = NULL;
|
||||
|
||||
/*
|
||||
|
||||
if (pDecoder->tmp_data_length > 0)
|
||||
{
|
||||
pkt_tmp.data = av_realloc(pkt_tmp.data, pkt_tmp.size + pDecoder->tmp_data_length);
|
||||
memmove(pkt_tmp.data + pDecoder->tmp_data_length, pkt_tmp.data, pkt_tmp.size);
|
||||
memcpy(pkt_tmp.data, pDecoder->tmp_data, pDecoder->tmp_data_length);
|
||||
pkt_tmp.size = pkt_tmp.size + pDecoder->tmp_data_length;
|
||||
} */
|
||||
|
||||
memcpy(pkt_tmp.data + pDecoder->tmp_data_length, &pkt_tmp.data, pkt_tmp.size);
|
||||
memcpy(&pkt_tmp.data, pDecoder->tmp_data, pDecoder->tmp_data_length);
|
||||
}
|
||||
|
||||
while (pkt_tmp.size > 0) {
|
||||
|
||||
if (!decoded_frame) {
|
||||
@@ -833,6 +718,7 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder
|
||||
|
||||
int len1 = avcodec_decode_audio4(pDecoder->pCodecCtx, decoded_frame, &got_frame, &pkt_tmp);
|
||||
|
||||
|
||||
//If an error occured, skip the frame
|
||||
if (len1 < 0){
|
||||
return 0;
|
||||
@@ -843,107 +729,54 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder
|
||||
pkt_tmp.data += len1;
|
||||
|
||||
if (got_frame){
|
||||
struct SwrContext *swr_ctx;
|
||||
int dst_nb_samples = 0, max_dst_nb_samples = 0, dst_linesize = 0;
|
||||
uint8_t **dst_data = NULL;
|
||||
int ret = 0;
|
||||
int dst_sample_rate = (pDecoder->pCodecCtx)->sample_rate;
|
||||
|
||||
swr_ctx = swr_alloc();
|
||||
|
||||
/* set options */
|
||||
av_opt_set_int(swr_ctx, "in_channel_layout", (pDecoder->pCodecCtx)->channel_layout, 0);
|
||||
av_opt_set_int(swr_ctx, "in_sample_rate", (pDecoder->pCodecCtx)->sample_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "in_sample_fmt", (pDecoder->pCodecCtx)->sample_fmt, 0);
|
||||
|
||||
av_opt_set_int(swr_ctx, "out_channel_layout", AV_CH_LAYOUT_STEREO, 0);
|
||||
av_opt_set_int(swr_ctx, "out_sample_rate", dst_sample_rate, 0);
|
||||
av_opt_set_sample_fmt(swr_ctx, "out_sample_fmt", AV_SAMPLE_FMT_S16, 0);
|
||||
|
||||
if (swr_init(swr_ctx) < 0)
|
||||
return 0;
|
||||
|
||||
/* compute the number of converted samples: buffering is avoided
|
||||
* ensuring that the output buffer will contain at least all the
|
||||
* converted input samples */
|
||||
max_dst_nb_samples = dst_nb_samples = av_rescale_rnd(
|
||||
decoded_frame->nb_samples, dst_sample_rate, (pDecoder->pCodecCtx)->sample_rate, AV_ROUND_UP);
|
||||
|
||||
if (alloc_samples_array_and_data(&dst_data, &dst_linesize, 2, dst_nb_samples, AV_SAMPLE_FMT_S16, 0) < 0)
|
||||
return 0;
|
||||
|
||||
/* compute destination number of samples */
|
||||
dst_nb_samples = av_rescale_rnd(swr_get_delay(swr_ctx, (pDecoder->pCodecCtx)->sample_rate) +
|
||||
decoded_frame->nb_samples, dst_sample_rate, (pDecoder->pCodecCtx)->sample_rate, AV_ROUND_UP);
|
||||
|
||||
if (dst_nb_samples > max_dst_nb_samples) {
|
||||
av_free(dst_data[0]);
|
||||
ret = av_samples_alloc(dst_data, &dst_linesize, 2,
|
||||
dst_nb_samples, AV_SAMPLE_FMT_S16, 1);
|
||||
if (ret < 0)
|
||||
return 0;
|
||||
max_dst_nb_samples = dst_nb_samples;
|
||||
}
|
||||
|
||||
if ((ret = swr_convert(swr_ctx, dst_data, dst_nb_samples, (const uint8_t **)decoded_frame->data, decoded_frame->nb_samples)) < 0)
|
||||
return 0;
|
||||
|
||||
int data_size = av_samples_get_buffer_size(&dst_linesize, 2, ret, AV_SAMPLE_FMT_S16, 1);
|
||||
|
||||
//Reserve enough memory for coping the result data
|
||||
if (dest_buffer_pos + data_size > pDecoder->max_buffer_size) {
|
||||
pDecoder->decoder.pBuffer = av_realloc(pDecoder->decoder.pBuffer, dest_buffer_pos + data_size);
|
||||
pDecoder->max_buffer_size = dest_buffer_pos + data_size;
|
||||
}
|
||||
|
||||
memcpy(pDecoder->decoder.pBuffer + dest_buffer_pos, dst_data[0], data_size);
|
||||
|
||||
//Increment the destination buffer pointers, copy the result to the output buffer
|
||||
dest_buffer_pos += data_size;
|
||||
pDecoder->decoder.buffer_size += data_size;
|
||||
|
||||
pts=0;
|
||||
|
||||
if(((lp_ac_package_data)pPackage)->ffpackage.dts != AV_NOPTS_VALUE){
|
||||
pts = ((lp_ac_package_data)pPackage)->ffpackage.dts * av_q2d(((lp_ac_data)pDec->pacInstance)->pFormatCtx->streams[pPackage->stream_index]->time_base);
|
||||
int data_size = av_samples_get_buffer_size(NULL, (pDecoder->pCodecCtx)->channels,
|
||||
decoded_frame->nb_samples,
|
||||
(pDecoder->pCodecCtx)->sample_fmt, 1);
|
||||
|
||||
//Reserve enough memory for coping the result data
|
||||
if (dest_buffer_pos + data_size > pDecoder->max_buffer_size) {
|
||||
pDecoder->decoder.pBuffer = av_realloc(pDecoder->decoder.pBuffer, dest_buffer_pos + data_size);
|
||||
pDecoder->max_buffer_size = dest_buffer_pos + data_size;
|
||||
}
|
||||
memcpy(pDecoder->decoder.pBuffer + dest_buffer_pos, decoded_frame->data[0], data_size);
|
||||
|
||||
pDec->video_clock = pts;
|
||||
} else {
|
||||
pts = pDec->video_clock;
|
||||
}
|
||||
//Increment the destination buffer pointers, copy the result to the output buffer
|
||||
dest_buffer_pos += data_size;
|
||||
pDecoder->decoder.buffer_size += data_size;
|
||||
|
||||
double bytes_per_second = 4 * pDec->stream_info.audio_info.samples_per_second;
|
||||
if (bytes_per_second > 0)
|
||||
pDec->video_clock += data_size / bytes_per_second;
|
||||
|
||||
pts=0;
|
||||
|
||||
if(((lp_ac_package_data)pPackage)->ffpackage.dts != AV_NOPTS_VALUE){
|
||||
pts = ((lp_ac_package_data)pPackage)->ffpackage.dts * av_q2d(((lp_ac_data)pDec->pacInstance)->pFormatCtx->streams[pPackage->stream_index]->time_base);
|
||||
|
||||
pDec->video_clock = pts;
|
||||
} else {
|
||||
pts = pDec->video_clock;
|
||||
}
|
||||
|
||||
double bytes_per_second = 2 * pDec->stream_info.audio_info.samples_per_second * pDec->stream_info.audio_info.channel_count;
|
||||
if (bytes_per_second > 0)
|
||||
pDec->video_clock += data_size / bytes_per_second;
|
||||
|
||||
pDec->timecode = pts;
|
||||
|
||||
/*
|
||||
if (pkt_tmp.size > 0)
|
||||
{
|
||||
pDecoder->tmp_data = av_malloc(pkt_tmp.size);
|
||||
memcpy(pDecoder->tmp_data, pkt_tmp.data, pkt_tmp.size);
|
||||
pDecoder->tmp_data_length = pkt_tmp.size;
|
||||
} else {
|
||||
if (pDecoder->tmp_data_length > 0)
|
||||
{
|
||||
av_free(pDecoder->tmp_data);
|
||||
pDecoder->tmp_data_length = 0;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
if (dst_data)
|
||||
av_freep(&dst_data[0]);
|
||||
av_freep(&dst_data);
|
||||
|
||||
swr_free(&swr_ctx);
|
||||
return 1;
|
||||
pDec->timecode = pts;
|
||||
|
||||
if (pkt_tmp.size > 0)
|
||||
{
|
||||
pDecoder->tmp_data = av_malloc(pkt_tmp.size);
|
||||
memcpy(pDecoder->tmp_data, &pkt_tmp.data, pkt_tmp.size);
|
||||
} else {
|
||||
av_free(pDecoder->tmp_data);
|
||||
pDecoder->tmp_data_length = 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
//av_free(pDecoder->tmp_data);
|
||||
//pDecoder->tmp_data_length = 0;
|
||||
av_free(pDecoder->tmp_data);
|
||||
pDecoder->tmp_data_length;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1019,10 +852,11 @@ int CALL_CONVT ac_get_audio_frame(lp_ac_instance pacInstance, lp_ac_decoder pDec
|
||||
while(done == 0 && pPackage != NULL){
|
||||
if (((lp_ac_package_data)pPackage)->package.stream_index == pDecoder->stream_index){
|
||||
done = ac_decode_package(pPackage, pDecoder);
|
||||
|
||||
ac_free_package(pPackage);
|
||||
|
||||
//if (((lp_ac_audio_decoder)pDecoder)->decoder.buffer_size < 17640)
|
||||
// done = 0;
|
||||
if (((lp_ac_audio_decoder)pDecoder)->decoder.buffer_size < 4096)
|
||||
done = 0;
|
||||
|
||||
if (done == 0)
|
||||
pPackage = ac_read_package(pacInstance);
|
||||
@@ -1118,8 +952,8 @@ int CALL_CONVT ac_seek(lp_ac_decoder pDecoder, int dir, int64_t target_pos) {
|
||||
if (((lp_ac_audio_decoder)pDecoder)->pCodecCtx->codec->flush != NULL)
|
||||
avcodec_flush_buffers(((lp_ac_audio_decoder)pDecoder)->pCodecCtx);
|
||||
|
||||
//av_free(((lp_ac_audio_decoder)pDecoder)->tmp_data);
|
||||
//((lp_ac_audio_decoder)pDecoder)->tmp_data_length = 0;
|
||||
av_free(((lp_ac_audio_decoder)pDecoder)->tmp_data);
|
||||
((lp_ac_audio_decoder)pDecoder)->tmp_data_length = 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
@@ -1152,7 +986,7 @@ void ac_free_audio_decoder(lp_ac_audio_decoder pDecoder) {
|
||||
av_free(pDecoder->decoder.pBuffer);
|
||||
|
||||
//Free the memory reserved for the temporary audio buffer
|
||||
//av_free(pDecoder->tmp_data);
|
||||
av_free(pDecoder->tmp_data);
|
||||
|
||||
//Free reserved memory for decoder record
|
||||
av_free(pDecoder);
|
||||
|
||||
@@ -113,7 +113,7 @@ struct _ac_audio_stream_info {
|
||||
/*Bits per sample. Can be 8 or 16 Bit.*/
|
||||
int bit_depth;
|
||||
/*Count of channels in the audio stream.*/
|
||||
int channel_count;
|
||||
int channel_count;
|
||||
};
|
||||
typedef struct _ac_audio_stream_info ac_audio_stream_info;
|
||||
|
||||
@@ -205,12 +205,6 @@ extern int CALL_CONVT ac_open(
|
||||
ac_seek_callback seek_proc,
|
||||
ac_openclose_callback close_proc,
|
||||
lp_ac_proberesult proberesult);
|
||||
|
||||
extern int CALL_CONVT ac_open2(
|
||||
lp_ac_instance pacInstance,
|
||||
const char* filename
|
||||
);
|
||||
|
||||
/*Closes an opened media file.*/
|
||||
extern void CALL_CONVT ac_close(lp_ac_instance pacInstance);
|
||||
|
||||
@@ -225,8 +219,6 @@ extern void CALL_CONVT ac_free_package(lp_ac_package pPackage);
|
||||
/*Creates an decoder for the specified stream number. Returns NIL if no decoder
|
||||
could be found.*/
|
||||
extern lp_ac_decoder CALL_CONVT ac_create_decoder(lp_ac_instance pacInstance, int nb);
|
||||
extern lp_ac_decoder CALL_CONVT ac_create_audio_decoder(lp_ac_instance pacInstance);
|
||||
extern lp_ac_decoder CALL_CONVT ac_create_video_decoder(lp_ac_instance pacInstance);
|
||||
/*Frees an created decoder.*/
|
||||
extern void CALL_CONVT ac_free_decoder(lp_ac_decoder pDecoder);
|
||||
/*Decodes a package using the specified decoder. The decodec data is stored in the
|
||||
|
||||
@@ -2,9 +2,9 @@ acinerella: acinerella.c acinerella.h
|
||||
gcc -c acinerella.c -I /usr/local/include
|
||||
|
||||
ifeq ($(shell uname),Linux)
|
||||
gcc -shared -o libacinerella.so acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lswresample
|
||||
gcc -shared -o libacinerella.so acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale
|
||||
strip libacinerella.so
|
||||
else
|
||||
gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32 -lswresample
|
||||
gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32
|
||||
strip acinerella.dll
|
||||
endif
|
||||
@@ -223,6 +223,10 @@ namespace Vocaluxe.Lib.Video
|
||||
private int _StreamID; // stream ID for stream closing
|
||||
private string _FileName; // current video file name
|
||||
|
||||
private FileStream _fs; // video file stream
|
||||
private TAc_read_callback _rc; // read callback for acinerella
|
||||
private TAc_seek_callback _sc; // seek callback for acinerella
|
||||
|
||||
private bool _FileOpened = false;
|
||||
|
||||
private float _VideoTimeBase = 0f; // frame time
|
||||
@@ -255,13 +259,16 @@ namespace Vocaluxe.Lib.Video
|
||||
private bool _terminated = false;
|
||||
|
||||
private Thread _thread;
|
||||
//AutoResetEvent EventDecode = new AutoResetEvent(false);
|
||||
SFrameBuffer[] _FrameBuffer = new SFrameBuffer[5];
|
||||
private bool _NewFrame = false;
|
||||
Object MutexFramebuffer = new Object();
|
||||
Object MutexSyncSignals = new Object();
|
||||
|
||||
public Decoder()
|
||||
{
|
||||
{
|
||||
_rc = new TAc_read_callback(read_proc);
|
||||
_sc = new TAc_seek_callback(seek_proc);
|
||||
_thread = new Thread(Execute);
|
||||
}
|
||||
|
||||
@@ -354,6 +361,7 @@ namespace Vocaluxe.Lib.Video
|
||||
|
||||
|
||||
UploadNewFrame(ref frame);
|
||||
//EventDecode.Set();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -365,6 +373,7 @@ namespace Vocaluxe.Lib.Video
|
||||
}
|
||||
UploadNewFrame(ref frame);
|
||||
VideoTime = _CurrentVideoTime;
|
||||
//EventDecode.Set();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
@@ -380,6 +389,7 @@ namespace Vocaluxe.Lib.Video
|
||||
_NoMoreFrames = false;
|
||||
_Finished = false;
|
||||
}
|
||||
//EventDecode.Set();
|
||||
|
||||
return true;
|
||||
}
|
||||
@@ -434,14 +444,17 @@ namespace Vocaluxe.Lib.Video
|
||||
_BufferFull = false;
|
||||
_skip = false;
|
||||
_NewFrame = false;
|
||||
//EventDecode.Set();
|
||||
}
|
||||
|
||||
private void Execute()
|
||||
{
|
||||
DoOpen();
|
||||
//EventDecode.Set();
|
||||
|
||||
while (!_terminated)
|
||||
{
|
||||
//if (EventDecode.WaitOne(10))
|
||||
{
|
||||
lock (MutexSyncSignals)
|
||||
{
|
||||
@@ -472,45 +485,56 @@ namespace Vocaluxe.Lib.Video
|
||||
|
||||
private void DoOpen()
|
||||
{
|
||||
bool ok = false;
|
||||
TAc_instance Instance = new TAc_instance();
|
||||
|
||||
_instance = CAcinerella.ac_init();
|
||||
int ret = -1;
|
||||
if ((ret = CAcinerella.ac_open2(_instance, _FileName)) < 0)
|
||||
{
|
||||
CLog.LogError("Error opening video file (Errorcode: " + ret.ToString() + "): " + _FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance));
|
||||
|
||||
if (!Instance.opened || Instance.info.duration == 0)
|
||||
{
|
||||
if (!Instance.opened)
|
||||
CLog.LogError("Can't open video file: " + _FileName);
|
||||
else
|
||||
CLog.LogError("Can't open video file (length = 0?): " + _FileName);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
_videodecoder = CAcinerella.ac_create_video_decoder(_instance);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
CLog.LogError("Can't create video decoder for file: " + _FileName + "; " + e.Message);
|
||||
return;
|
||||
}
|
||||
_fs = new FileStream(_FileName, FileMode.Open, FileAccess.Read, FileShare.Read);
|
||||
|
||||
if (_videodecoder == IntPtr.Zero)
|
||||
|
||||
_instance = CAcinerella.ac_init();
|
||||
CAcinerella.ac_open(_instance, IntPtr.Zero, null, _rc, _sc, null, IntPtr.Zero);
|
||||
|
||||
Instance = (TAc_instance)Marshal.PtrToStructure(_instance, typeof(TAc_instance));
|
||||
ok = true;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
CLog.LogError("Can't create video decoder for file: " + _FileName);
|
||||
CLog.LogError("Error opening video file: " + _FileName);
|
||||
ok = false;
|
||||
}
|
||||
|
||||
|
||||
if (!Instance.opened || !ok)
|
||||
{
|
||||
//Free();
|
||||
return;
|
||||
}
|
||||
|
||||
_Duration = (float)Instance.info.duration / 1000f;
|
||||
|
||||
int VideoStreamIndex = -1;
|
||||
|
||||
TAc_stream_info Info = new TAc_stream_info();
|
||||
for (int i = 0; i < Instance.stream_count; i++)
|
||||
{
|
||||
CAcinerella.ac_get_stream_info(_instance, i, out Info);
|
||||
|
||||
if (Info.stream_type == TAc_stream_type.AC_STREAM_TYPE_VIDEO)
|
||||
{
|
||||
_videodecoder = CAcinerella.ac_create_decoder(_instance, i);
|
||||
|
||||
VideoStreamIndex = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (VideoStreamIndex < 0)
|
||||
{
|
||||
//Free();
|
||||
return;
|
||||
}
|
||||
|
||||
TAc_decoder Videodecoder = (TAc_decoder)Marshal.PtrToStructure(_videodecoder, typeof(TAc_decoder));
|
||||
|
||||
_Width = Videodecoder.stream_info.video_info.frame_width;
|
||||
@@ -677,6 +701,9 @@ namespace Vocaluxe.Lib.Video
|
||||
_NewFrame = false;
|
||||
}
|
||||
}
|
||||
|
||||
//if (!_BufferFull)
|
||||
// EventDecode.Set();
|
||||
}
|
||||
|
||||
private void UploadNewFrame(ref STexture frame)
|
||||
@@ -705,6 +732,7 @@ namespace Vocaluxe.Lib.Video
|
||||
_CurrentVideoTime = _FrameBuffer[num].time;
|
||||
}
|
||||
_Finished = false;
|
||||
//EventDecode.Set();
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -758,5 +786,23 @@ namespace Vocaluxe.Lib.Video
|
||||
_Closeproc(_StreamID);
|
||||
}
|
||||
#endregion Threading
|
||||
|
||||
#region Callbacks
|
||||
private Int32 read_proc(IntPtr sender, IntPtr buf, Int32 size)
|
||||
{
|
||||
Int32 r = 0;
|
||||
|
||||
byte[] bb = new byte[size];
|
||||
r = _fs.Read(bb, 0, size);
|
||||
Marshal.Copy(bb, 0, buf, size);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
private Int64 seek_proc(IntPtr sender, Int64 pos, Int32 whence)
|
||||
{
|
||||
return (Int64)_fs.Seek((long)pos, (SeekOrigin)whence);
|
||||
}
|
||||
#endregion Callbacks
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user