aboutsummaryrefslogtreecommitdiffstats
path: root/Game/Code/lib/acinerella
diff options
context:
space:
mode:
Diffstat (limited to 'Game/Code/lib/acinerella')
-rw-r--r--Game/Code/lib/acinerella/acinerella.c129
1 files changed, 64 insertions, 65 deletions
diff --git a/Game/Code/lib/acinerella/acinerella.c b/Game/Code/lib/acinerella/acinerella.c
index 5e7c4df2..509346a7 100644
--- a/Game/Code/lib/acinerella/acinerella.c
+++ b/Game/Code/lib/acinerella/acinerella.c
@@ -25,7 +25,7 @@
#include <libswscale/swscale.h>
#include <string.h>
-#define AUDIO_BUFFER_BASE_SIZE ((AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2)
+#define AUDIO_BUFFER_BASE_SIZE AVCODEC_MAX_AUDIO_FRAME_SIZE
//This struct represents one Acinerella video object.
@@ -78,6 +78,7 @@ struct _ac_audio_decoder {
ac_decoder decoder;
int sought;
double last_timecode;
+ char *tmp_buf;
int max_buffer_size;
AVCodec *pCodec;
AVCodecContext *pCodecCtx;
@@ -113,7 +114,20 @@ void init_info(lp_ac_file_info info)
info->bitrate = -1;
}
-lp_ac_instance CALL_CONVT ac_init(void) {
+int av_initialized = 0;
+void ac_init_ffmpeg()
+{
+ if(!av_initialized)
+ {
+ avcodec_register_all();
+ av_register_all();
+ av_initialized = 1;
+ }
+}
+
+lp_ac_instance CALL_CONVT ac_init(void) {
+ ac_init_ffmpeg();
+
//Allocate a new instance of the videoplayer data and return it
lp_ac_data ptmp;
ptmp = (lp_ac_data)av_malloc(sizeof(ac_data));
@@ -137,8 +151,6 @@ void CALL_CONVT ac_free(lp_ac_instance pacInstance) {
}
}
-lp_ac_data last_instance;
-
static int io_read(void *opaque, uint8_t *buf, int buf_size)
{
if (((lp_ac_data)(opaque))->read_proc != NULL) {
@@ -161,37 +173,6 @@ static int64_t io_seek(void *opaque, int64_t pos, int whence)
return -1;
}
-static AVInputFormat *_av_probe_input_format2(AVProbeData *pd, int *score_max)
-{
- AVInputFormat *fmt1, *fmt;
- int score;
-
- fmt = NULL;
- for(fmt1 = first_iformat; fmt1 != NULL; fmt1 = fmt1->next) {
- score = 0;
-
- //Only handle formats which require a file to be opened (test)
- if (fmt1->flags & AVFMT_NOFILE) {
- continue;
- }
-
- if (fmt1->read_probe) {
- score = fmt1->read_probe(pd);
- } else if (fmt1->extensions) {
- if (av_match_ext(pd->filename, fmt1->extensions)) {
- score = 50;
- }
- }
- if (score > *score_max) {
- *score_max = score;
- fmt = fmt1;
- } else if (score == *score_max) {
- fmt = NULL;
- }
- }
- return fmt;
-}
-
uint64_t global_video_pkt_pts = AV_NOPTS_VALUE;
int ac_get_buffer(struct AVCodecContext *c, AVFrame *pic) {
@@ -214,23 +195,33 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(
int* score_max)
{
AVProbeData pd;
+ AVInputFormat *fmt = NULL;
//Initialize FFMpeg libraries
- avcodec_register_all();
- av_register_all();
+ ac_init_ffmpeg();
//Set the filename
pd.filename = "";
if (filename) {
pd.filename = filename;
}
-
+
+ //The given buffer has to be copied to a new one, which is aligned and padded
+ char *aligned_buf = av_malloc(bufsize + AVPROBE_PADDING_SIZE);
+ memset(aligned_buf, 0, bufsize + AVPROBE_PADDING_SIZE);
+ memcpy(aligned_buf, buf, bufsize);
+
//Set the probe data buffer
- pd.buf = buf;
+ pd.buf = aligned_buf;
pd.buf_size = bufsize;
//Test it
- return (lp_ac_proberesult) _av_probe_input_format2(&pd, score_max);
+ fmt = av_probe_input_format2(&pd, 1, score_max);
+
+ //Free the temporary buffer
+ av_free(aligned_buf);
+
+ return (lp_ac_proberesult)fmt;
}
#define PROBE_BUF_MIN 2048
@@ -256,7 +247,8 @@ AVInputFormat* ac_probe_input_stream(
int score = AVPROBE_SCORE_MAX / 4;
//Allocate some memory for the current probe buffer
- void* tmp_buf = av_malloc(probe_size);
+ void* tmp_buf = av_malloc(probe_size); //Unaligned memory would also be ok here
+ memset(tmp_buf, 0, probe_size);
//Copy the old data to the new buffer
if (*buf) {
@@ -296,10 +288,7 @@ int CALL_CONVT ac_open(
lp_ac_proberesult proberesult)
{
pacInstance->opened = 0;
-
- //Set last instance
- last_instance = (lp_ac_data)pacInstance;
-
+
//Store the given parameters in the ac Instance
((lp_ac_data)pacInstance)->sender = sender;
((lp_ac_data)pacInstance)->open_proc = open_proc;
@@ -493,6 +482,7 @@ lp_ac_package CALL_CONVT ac_read_package(lp_ac_instance pacInstance) {
if (av_read_frame(((lp_ac_data)(pacInstance))->pFormatCtx, &Package) >= 0) {
//Reserve memory
lp_ac_package_data pTmp = (lp_ac_package_data)(av_malloc(sizeof(ac_package_data)));
+ memset(pTmp, 0, sizeof(ac_package_data));
//Set package data
pTmp->package.stream_index = Package.stream_index;
@@ -539,6 +529,7 @@ void* ac_create_video_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info
//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;
@@ -582,6 +573,7 @@ void* ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info
//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;
@@ -603,10 +595,13 @@ void* ac_create_audio_decoder(lp_ac_instance pacInstance, lp_ac_stream_info info
return NULL;
}
- //Reserve a buffer
- pDecoder->max_buffer_size = AUDIO_BUFFER_BASE_SIZE;
- pDecoder->decoder.pBuffer = av_malloc(AUDIO_BUFFER_BASE_SIZE);
+ //Initialize the buffers
+ pDecoder->decoder.pBuffer = NULL; //av_malloc(AUDIO_BUFFER_BASE_SIZE);
pDecoder->decoder.buffer_size = 0;
+ pDecoder->max_buffer_size = 0;
+
+ //Reserve the temporary buffer which contains AVCODEC_MAX_AUDIO_FRAME_SIZE bytes
+ pDecoder->tmp_buf = av_malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE);
return (void*)pDecoder;
}
@@ -698,7 +693,6 @@ int ac_decode_video_package(lp_ac_package pPackage, lp_ac_video_decoder pDecoder
int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder) {
//Variables describing the destination buffer
- int dest_buffer_size = pDecoder->max_buffer_size;
int dest_buffer_pos = 0;
//Make a copy of the package read by avformat, so that we can move the data pointers around
@@ -709,31 +703,35 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder
while (pkt_tmp.size > 0) {
//Set the size of bytes that can be written to the current size of the destination buffer
- int size = dest_buffer_size;
+ int size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
//Decode a piece of the audio buffer. len1 contains the count of bytes read from the soure buffer.
int len1 = avcodec_decode_audio3(
- pDecoder->pCodecCtx, (int16_t*)(pDecoder->decoder.pBuffer + dest_buffer_pos),
+ pDecoder->pCodecCtx, (int16_t*)(pDecoder->tmp_buf),
&size, &pkt_tmp
);
//If an error occured, skip the frame
- if (len1 <= 0)
+ if (len1 < 0){
return 0;
-
- if (size <= 0)
- continue;
-
+ }
+
//Increment the source buffer pointers
pkt_tmp.size -= len1;
pkt_tmp.data += len1;
- //Increment the destination buffer pointers
- dest_buffer_size -= size;
- dest_buffer_pos += size;
- pDecoder->decoder.buffer_size = dest_buffer_pos;
-
- return 1;
+ if (size > 0){
+ //Reserve enough memory for coping the result data
+ if (dest_buffer_pos + size > pDecoder->max_buffer_size) {
+ pDecoder->decoder.pBuffer = av_realloc(pDecoder->decoder.pBuffer, dest_buffer_pos + size);
+ pDecoder->max_buffer_size = dest_buffer_pos + size;
+ }
+ memcpy(pDecoder->decoder.pBuffer + dest_buffer_pos, pDecoder->tmp_buf, size);
+
+ //Increment the destination buffer pointers, copy the result to the output buffer
+ dest_buffer_pos += size;
+ pDecoder->decoder.buffer_size += size;
+ }
}
return 1;
@@ -800,8 +798,7 @@ int CALL_CONVT ac_seek(lp_ac_decoder pDecoder, int dir, int64_t target_pos) {
}
//Free video decoder
-void ac_free_video_decoder(lp_ac_video_decoder pDecoder) {
-// av_free(pDecoder->decoder.pBuffer);
+void ac_free_video_decoder(lp_ac_video_decoder pDecoder) {
av_free(pDecoder->pFrame);
av_free(pDecoder->pFrameRGB);
if (pDecoder->pSwsCtx != NULL) {
@@ -809,7 +806,6 @@ void ac_free_video_decoder(lp_ac_video_decoder pDecoder) {
}
avcodec_close(pDecoder->pCodecCtx);
-
//Free reserved memory for the buffer
av_free(pDecoder->decoder.pBuffer);
@@ -824,6 +820,9 @@ void ac_free_audio_decoder(lp_ac_audio_decoder pDecoder) {
//Free reserved memory for the buffer
av_free(pDecoder->decoder.pBuffer);
+
+ //Free the memory reserved for the temporary audio buffer
+ av_free(pDecoder->tmp_buf);
//Free reserved memory for decoder record
av_free(pDecoder);