mirror of
https://gitee.com/Vancouver2017/luban-lite.git
synced 2025-12-24 04:58:54 +00:00
v1.1.1
This commit is contained in:
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
|
||||
206
packages/artinchip/mpp/middle_media/base/parser/flac/flac.c
Normal file
206
packages/artinchip/mpp/middle_media/base/parser/flac/flac.c
Normal 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;
|
||||
}
|
||||
38
packages/artinchip/mpp/middle_media/base/parser/flac/flac.h
Normal file
38
packages/artinchip/mpp/middle_media/base/parser/flac/flac.h
Normal 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
|
||||
Reference in New Issue
Block a user