This commit is contained in:
刘可亮
2024-10-30 16:50:31 +08:00
parent 0ef85b55da
commit 661e71562d
458 changed files with 46555 additions and 12133 deletions

View File

@@ -16,7 +16,9 @@
#ifdef AIC_MPP_AVI_DEMUX
#include "aic_avi_parser.h"
#endif
#ifdef AIC_MPP_FLAC_DEMUX
#include "aic_flac_parser.h"
#endif
struct aic_parser_create_tbl {
char file_type[7];
@@ -33,6 +35,9 @@ struct aic_parser_create_tbl create_tbl[] = {
#ifdef AIC_MPP_AVI_DEMUX
{"avi", 3, aic_avi_parser_create},
#endif
#ifdef AIC_MPP_FLAC_DEMUX
{"flac", 4, aic_flac_parser_create},
#endif
};
s32 aic_parser_create(unsigned char *uri, struct aic_parser **parser)
{

View File

@@ -0,0 +1,137 @@
/*
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: <che.jiang@artinchip.com>
* Desc: aic flac parser
*/
#include <malloc.h>
#include <string.h>
#include <stddef.h>
#include <inttypes.h>
#include <fcntl.h>
#include "aic_mov_parser.h"
#include "mpp_log.h"
#include "mpp_mem.h"
#include "mpp_dec_type.h"
#include "aic_stream.h"
#include "flac.h"
#include "aic_flac_parser.h"
s32 flac_peek(struct aic_parser * parser, struct aic_parser_packet *pkt)
{
struct aic_flac_parser *flac_parser = (struct aic_flac_parser *)parser;
return flac_peek_packet(flac_parser,pkt);
}
s32 flac_read(struct aic_parser * parser, struct aic_parser_packet *pkt)
{
struct aic_flac_parser *flac_parser = (struct aic_flac_parser *)parser;
return flac_read_packet(flac_parser,pkt);
}
s32 flac_get_media_info(struct aic_parser *parser, struct aic_parser_av_media_info *media)
{
int i;
struct aic_flac_parser *c = (struct aic_flac_parser *)parser;
media->has_video = 0;
for (i = 0; i < c->nb_streams; i++) {
struct flac_stream_ctx *st = c->streams[i];
if (st->codecpar.codec_type == MPP_MEDIA_TYPE_AUDIO) {
media->has_audio = 1;
media->audio_stream.codec_type = MPP_CODEC_AUDIO_DECODER_FLAC;
media->audio_stream.bits_per_sample =
st->codecpar.bits_per_coded_sample;
media->audio_stream.nb_channel = st->codecpar.channels;
media->audio_stream.sample_rate = st->codecpar.sample_rate;
if (st->codecpar.extradata_size > 0) {
media->audio_stream.extra_data_size =
st->codecpar.extradata_size;
media->audio_stream.extra_data = st->codecpar.extradata;
}
logi("audio bits_per_sample: %d",
st->codecpar.bits_per_coded_sample);
logi("audio channels: %d", st->codecpar.channels);
logi("audio sample_rate: %d", st->codecpar.sample_rate);
logi("audio total_samples: %" PRId64 "", st->total_samples);
} else {
loge("unknown stream(%d) type: %d", i, st->codecpar.codec_type);
}
}
media->file_size = c->file_size;
return 0;
}
s32 flac_seek(struct aic_parser *parser, s64 time)
{
struct aic_flac_parser *flac_parser = (struct aic_flac_parser *)parser;
return flac_seek_packet(flac_parser,time);
}
s32 flac_init(struct aic_parser *parser)
{
struct aic_flac_parser *flac_parser = (struct aic_flac_parser *)parser;
if (flac_read_header(flac_parser)) {
loge("flac read header failed");
return -1;
}
return 0;
}
s32 flac_destroy(struct aic_parser *parser)
{
struct aic_flac_parser *flac_parser = (struct aic_flac_parser *)parser;
if (flac_parser == NULL) {
return -1;
}
flac_close(flac_parser);
aic_stream_close(flac_parser->stream);
mpp_free(flac_parser);
return 0;
}
s32 aic_flac_parser_create(unsigned char *uri, struct aic_parser **parser)
{
s32 ret = 0;
struct aic_flac_parser *flac_parser = NULL;
flac_parser = (struct aic_flac_parser *)mpp_alloc(sizeof(struct aic_flac_parser));
if (flac_parser == NULL) {
loge("mpp_alloc aic_parser for flac failed!!!!!\n");
ret = -1;
goto exit;
}
memset(flac_parser, 0, sizeof(struct aic_flac_parser));
if (aic_stream_open((char *)uri, &flac_parser->stream, O_RDONLY) < 0) {
loge("stream open %s fail", uri);
ret = -1;
goto exit;
}
flac_parser->base.get_media_info = flac_get_media_info;
flac_parser->base.peek = flac_peek;
flac_parser->base.read = flac_read;
flac_parser->base.destroy = flac_destroy;
flac_parser->base.seek = flac_seek;
flac_parser->base.init = flac_init;
*parser = &flac_parser->base;
return ret;
exit:
if (flac_parser->stream) {
aic_stream_close(flac_parser->stream);
}
if (flac_parser) {
mpp_free(flac_parser);
}
return ret;
}

View File

@@ -0,0 +1,26 @@
/*
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: <che.jiang@artinchip.com>
* Desc: aic flac parser
*/
#ifndef __AIC_FLAC_PARSER_H__
#define __AIC_FLAC_PARSER_H__
#include "aic_parser.h"
#include "aic_stream.h"
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */
s32 aic_flac_parser_create(unsigned char* uri, struct aic_parser **parser);
#ifdef __cplusplus
}
#endif /* End of #ifdef __cplusplus */
#endif

View File

@@ -0,0 +1,206 @@
/*
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: <che.jiang@artinchip.com>
* Desc: flac parser
*/
#include "flac.h"
#include "aic_stream.h"
#include "aic_tag.h"
#include "mpp_log.h"
#include "mpp_mem.h"
#include <inttypes.h>
#include <rtthread.h>
#include <stdlib.h>
#define SEEKPOINT_SIZE 18
#define FLAC_STREAMINFO_SIZE 34
#define FLAC_MAX_CHANNELS 8
#define FLAC_MIN_BLOCKSIZE 16
#define FLAC_MAX_BLOCKSIZE 65535
#define FLAC_MIN_FRAME_SIZE 11
#define RAW_PACKET_SIZE 1024
enum {
FLAC_CHMODE_INDEPENDENT = 0,
FLAC_CHMODE_LEFT_SIDE = 1,
FLAC_CHMODE_RIGHT_SIDE = 2,
FLAC_CHMODE_MID_SIDE = 3,
};
enum {
FLAC_METADATA_TYPE_STREAMINFO = 0,
FLAC_METADATA_TYPE_PADDING,
FLAC_METADATA_TYPE_APPLICATION,
FLAC_METADATA_TYPE_SEEKTABLE,
FLAC_METADATA_TYPE_VORBIS_COMMENT,
FLAC_METADATA_TYPE_CUESHEET,
FLAC_METADATA_TYPE_PICTURE,
FLAC_METADATA_TYPE_INVALID = 127
};
static struct flac_stream_ctx *flac_new_stream(struct aic_flac_parser *s)
{
struct flac_stream_ctx *sc;
sc = (struct flac_stream_ctx *)mpp_alloc(sizeof(struct flac_stream_ctx));
if (sc == NULL) {
return NULL;
}
memset(sc, 0, sizeof(struct flac_stream_ctx));
sc->index = s->nb_streams;
s->streams[s->nb_streams++] = sc;
return sc;
}
static inline void flac_parse_block_header(const uint8_t *block_header,
int *last, int *type, int *size)
{
int tmp = block_header[0];
if (last)
*last = tmp & 0x80;
if (type)
*type = tmp & 0x7F;
if (size)
*size = AIC_RB24(block_header + 1);
}
int flac_read_header(struct aic_flac_parser *s)
{
int ret, metadata_last = 0, metadata_type, metadata_size, found_streaminfo = 0;
uint8_t header[4];
uint8_t *buffer = NULL;
struct flac_stream_ctx *st = flac_new_stream(s);
if (!st)
return PARSER_NOMEM;
st->codecpar.codec_type = MPP_MEDIA_TYPE_AUDIO;
st->codecpar.codec_id = MPP_CODEC_AUDIO_DECODER_FLAC;
s->file_size = aic_stream_size(s->stream);
/* the parameters will be extracted from the compressed bitstream */
/* if fLaC marker is not found, assume there is no header */
if (aic_stream_rl32(s->stream) != MKTAG('f', 'L', 'a', 'C')) {
aic_stream_seek(s->stream, -4, SEEK_CUR);
return PARSER_OK;
}
/* process metadata blocks */
while ((aic_stream_tell(s->stream) < s->file_size) && !metadata_last) {
if (aic_stream_read(s->stream, header, 4) != 4)
return PARSER_INVALIDDATA;
flac_parse_block_header(header, &metadata_last, &metadata_type,
&metadata_size);
switch (metadata_type) {
/* allocate and read metadata block for supported types */
case FLAC_METADATA_TYPE_STREAMINFO:
buffer = mpp_alloc(metadata_size + 64);
if (!buffer) {
return PARSER_NOMEM;
}
if (aic_stream_read(s->stream, buffer, metadata_size) != metadata_size) {
return PARSER_NODATA;
}
break;
/* skip metadata block for unsupported types */
default:
ret = aic_stream_skip(s->stream, metadata_size);
if (ret < 0)
return ret;
}
if (metadata_type == FLAC_METADATA_TYPE_STREAMINFO) {
/* STREAMINFO can only occur once */
if (found_streaminfo) {
return PARSER_INVALIDDATA;
}
if (metadata_size != FLAC_STREAMINFO_SIZE) {
return PARSER_INVALIDDATA;
}
found_streaminfo = 1;
st->codecpar.sample_rate = AIC_RB24(buffer + 10) >> 4;
st->codecpar.channels = ((*(buffer + 12) >> 1) & 0x7) + 1;
st->codecpar.bits_per_coded_sample = ((AIC_RB16(buffer + 12) >> 4) & 0x1f) + 1;
st->total_samples = (AIC_RB64(buffer + 13) >> 24) & ((1ULL << 36) - 1);
mpp_free(buffer);
}
}
aic_stream_seek(s->stream, 0, SEEK_SET);
return PARSER_OK;
}
int flac_close(struct aic_flac_parser *s)
{
int i;
for (i = 0; i < s->nb_streams; i++) {
struct flac_stream_ctx *st = s->streams[i];
if (!st) {
continue;
}
mpp_free(st);
}
return PARSER_OK;
}
int flac_seek_packet(struct aic_flac_parser *s, s64 seek_time)
{
return PARSER_ERROR;
}
int flac_peek_packet(struct aic_flac_parser *s, struct aic_parser_packet *pkt)
{
int64_t pos;
static int64_t count = 0;
pos = aic_stream_tell(s->stream);
if (pos >= s->file_size) {
logd("Peek PARSER_EOS,%" PRId64 ",%" PRId64 "\n", pos, s->file_size);
return PARSER_EOS;
}
if (pos + RAW_PACKET_SIZE >= s->file_size)
pkt->size = s->file_size - pos;
else
pkt->size = RAW_PACKET_SIZE;
pkt->type = MPP_MEDIA_TYPE_AUDIO;
pkt->pts = count++;
return PARSER_OK;
}
int flac_read_packet(struct aic_flac_parser *s, struct aic_parser_packet *pkt)
{
int64_t pos;
int ret;
pos = aic_stream_tell(s->stream);
if (pos >= s->file_size) {
loge("PARSER_EOS,%" PRId64 ",%" PRId64 "\n", pos, s->file_size);
return PARSER_EOS;
}
ret = aic_stream_read(s->stream, pkt->data, pkt->size);
pos = aic_stream_tell(s->stream);
if (pos >= s->file_size) {
printf("Read PARSER_EOS,%" PRId64 ",%" PRId64 "\n", pos, s->file_size);
pkt->flag |= PACKET_EOS;
} else {
if (ret != pkt->size) {
loge("hope_len:%d,ret:%d\n", pkt->size, ret);
}
}
return PARSER_OK;
}

View File

@@ -0,0 +1,38 @@
/*
* Copyright (C) 2020-2024 ArtInChip Technology Co. Ltd
*
* SPDX-License-Identifier: Apache-2.0
*
* Author: <che.jiang@artinchip.com>
* Desc: flac parser
*/
#ifndef __FLAC_H__
#define __FLAC_H__
#include "aic_parser.h"
#include <unistd.h>
#include "aic_tag.h"
struct flac_stream_ctx {
int index;
uint64_t total_samples;
struct aic_codec_param codecpar;
};
#define FLAC_MAX_TRACK_NUM 1
struct aic_flac_parser {
struct aic_parser base;
struct aic_stream *stream;
uint64_t file_size;
int nb_streams;
struct flac_stream_ctx *streams[FLAC_MAX_TRACK_NUM];
};
int flac_read_header(struct aic_flac_parser *s);
int flac_close(struct aic_flac_parser *s);
int flac_peek_packet(struct aic_flac_parser *s, struct aic_parser_packet *pkt);
int flac_seek_packet(struct aic_flac_parser *s, s64 seek_time);
int flac_read_packet(struct aic_flac_parser *s, struct aic_parser_packet *pkt);
#endif