the changed acinerella files for last commit
This commit is contained in:
1 parent
88573e6c45
commit
9bcf209d49
3 files changed
+356
-182
No files matched your search
@@ -23,6 +23,7 @@
|
||||
#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
|
||||
@@ -80,8 +81,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;
|
||||
@@ -204,7 +205,7 @@ lp_ac_proberesult CALL_CONVT ac_probe_input_buffer(
|
||||
return (lp_ac_proberesult)fmt;
|
||||
}
|
||||
|
||||
#define PROBE_BUF_MIN 2048
|
||||
#define PROBE_BUF_MIN 1024
|
||||
#define PROBE_BUF_MAX (1<<20)
|
||||
|
||||
|
||||
@@ -338,7 +339,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;
|
||||
}
|
||||
@@ -350,6 +351,39 @@ 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
|
||||
@@ -404,42 +438,13 @@ 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 =
|
||||
((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;
|
||||
}
|
||||
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;
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -501,89 +506,189 @@ 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));
|
||||
|
||||
//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
|
||||
}
|
||||
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));
|
||||
|
||||
pDecoder->pCodecCtx->thread_count = 1; //this is for HT CPUs, it should be
|
||||
// tested if there is a better solution
|
||||
//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
|
||||
|
||||
//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);
|
||||
//Open codec
|
||||
if (avcodec_open2(pDecoder->pCodecCtx, pDecoder->pCodec, NULL) < 0)
|
||||
return NULL; //Codec could not have been opened
|
||||
|
||||
//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;
|
||||
//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;
|
||||
}
|
||||
|
||||
//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;
|
||||
|
||||
//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 = NULL; //av_malloc(AUDIO_BUFFER_BASE_SIZE);
|
||||
pDecoder->decoder.buffer_size = 0;
|
||||
pDecoder->max_buffer_size = 0;
|
||||
|
||||
//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);
|
||||
|
||||
pDecoder->tmp_data = NULL;
|
||||
pDecoder->tmp_data_length = 0;
|
||||
|
||||
return (void*)pDecoder;
|
||||
//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;
|
||||
|
||||
//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_decoder(lp_ac_instance pacInstance, int nb) {
|
||||
@@ -595,12 +700,15 @@ 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;
|
||||
@@ -643,13 +751,7 @@ 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,
|
||||
@@ -687,6 +789,18 @@ 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
|
||||
@@ -694,17 +808,18 @@ 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) {
|
||||
@@ -718,7 +833,6 @@ 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;
|
||||
@@ -729,54 +843,107 @@ int ac_decode_audio_package(lp_ac_package pPackage, lp_ac_audio_decoder pDecoder
|
||||
pkt_tmp.data += len1;
|
||||
|
||||
if (got_frame){
|
||||
|
||||
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);
|
||||
|
||||
//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);
|
||||
|
||||
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;
|
||||
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;
|
||||
|
||||
pDec->timecode = pts;
|
||||
swr_ctx = swr_alloc();
|
||||
|
||||
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;
|
||||
}
|
||||
/* 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);
|
||||
|
||||
return 1;
|
||||
pDec->video_clock = pts;
|
||||
} else {
|
||||
pts = pDec->video_clock;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
av_free(pDecoder->tmp_data);
|
||||
pDecoder->tmp_data_length;
|
||||
//av_free(pDecoder->tmp_data);
|
||||
//pDecoder->tmp_data_length = 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -852,11 +1019,10 @@ 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 < 4096)
|
||||
done = 0;
|
||||
//if (((lp_ac_audio_decoder)pDecoder)->decoder.buffer_size < 17640)
|
||||
// done = 0;
|
||||
|
||||
if (done == 0)
|
||||
pPackage = ac_read_package(pacInstance);
|
||||
@@ -952,8 +1118,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;
|
||||
}
|
||||
@@ -986,7 +1152,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,6 +205,12 @@ 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);
|
||||
|
||||
@@ -219,6 +225,8 @@ 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
|
||||
gcc -shared -o libacinerella.so acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lswresample
|
||||
strip libacinerella.so
|
||||
else
|
||||
gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32
|
||||
gcc -shared -o acinerella.dll -fPIC acinerella.o -lavformat -lavcodec -lavutil -lm -lswscale -lws2_32 -lswresample
|
||||
strip acinerella.dll
|
||||
endif
|
||||
Reference in new issue
Block a user