Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
Download
52868 views
1
/*
2
* MPEG-2/4 AAC ADTS to MPEG-4 Audio Specific Configuration bitstream filter
3
* Copyright (c) 2009 Alex Converse <[email protected]>
4
*
5
* This file is part of FFmpeg.
6
*
7
* FFmpeg is free software; you can redistribute it and/or
8
* modify it under the terms of the GNU Lesser General Public
9
* License as published by the Free Software Foundation; either
10
* version 2.1 of the License, or (at your option) any later version.
11
*
12
* FFmpeg is distributed in the hope that it will be useful,
13
* but WITHOUT ANY WARRANTY; without even the implied warranty of
14
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15
* Lesser General Public License for more details.
16
*
17
* You should have received a copy of the GNU Lesser General Public
18
* License along with FFmpeg; if not, write to the Free Software
19
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20
*/
21
22
#include "avcodec.h"
23
#include "aacadtsdec.h"
24
#include "put_bits.h"
25
#include "get_bits.h"
26
#include "mpeg4audio.h"
27
#include "internal.h"
28
29
typedef struct AACBSFContext {
30
int first_frame_done;
31
} AACBSFContext;
32
33
/**
34
* This filter creates an MPEG-4 AudioSpecificConfig from an MPEG-2/4
35
* ADTS header and removes the ADTS header.
36
*/
37
static int aac_adtstoasc_filter(AVBitStreamFilterContext *bsfc,
38
AVCodecContext *avctx, const char *args,
39
uint8_t **poutbuf, int *poutbuf_size,
40
const uint8_t *buf, int buf_size,
41
int keyframe)
42
{
43
GetBitContext gb;
44
PutBitContext pb;
45
AACADTSHeaderInfo hdr;
46
47
AACBSFContext *ctx = bsfc->priv_data;
48
49
init_get_bits(&gb, buf, AAC_ADTS_HEADER_SIZE*8);
50
51
*poutbuf = (uint8_t*) buf;
52
*poutbuf_size = buf_size;
53
54
if (avctx->extradata)
55
if (show_bits(&gb, 12) != 0xfff)
56
return 0;
57
58
if (avpriv_aac_parse_header(&gb, &hdr) < 0) {
59
av_log(avctx, AV_LOG_ERROR, "Error parsing ADTS frame header!\n");
60
return AVERROR_INVALIDDATA;
61
}
62
63
if (!hdr.crc_absent && hdr.num_aac_frames > 1) {
64
avpriv_report_missing_feature(avctx,
65
"Multiple RDBs per frame with CRC");
66
return AVERROR_PATCHWELCOME;
67
}
68
69
buf += AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;
70
buf_size -= AAC_ADTS_HEADER_SIZE + 2*!hdr.crc_absent;
71
72
if (!ctx->first_frame_done) {
73
int pce_size = 0;
74
uint8_t pce_data[MAX_PCE_SIZE];
75
if (!hdr.chan_config) {
76
init_get_bits(&gb, buf, buf_size * 8);
77
if (get_bits(&gb, 3) != 5) {
78
avpriv_report_missing_feature(avctx,
79
"PCE-based channel configuration "
80
"without PCE as first syntax "
81
"element");
82
return AVERROR_PATCHWELCOME;
83
}
84
init_put_bits(&pb, pce_data, MAX_PCE_SIZE);
85
pce_size = avpriv_copy_pce_data(&pb, &gb)/8;
86
flush_put_bits(&pb);
87
buf_size -= get_bits_count(&gb)/8;
88
buf += get_bits_count(&gb)/8;
89
}
90
av_free(avctx->extradata);
91
avctx->extradata_size = 2 + pce_size;
92
avctx->extradata = av_mallocz(avctx->extradata_size + AV_INPUT_BUFFER_PADDING_SIZE);
93
if (!avctx->extradata) {
94
avctx->extradata_size = 0;
95
return AVERROR(ENOMEM);
96
}
97
98
init_put_bits(&pb, avctx->extradata, avctx->extradata_size);
99
put_bits(&pb, 5, hdr.object_type);
100
put_bits(&pb, 4, hdr.sampling_index);
101
put_bits(&pb, 4, hdr.chan_config);
102
put_bits(&pb, 1, 0); //frame length - 1024 samples
103
put_bits(&pb, 1, 0); //does not depend on core coder
104
put_bits(&pb, 1, 0); //is not extension
105
flush_put_bits(&pb);
106
if (pce_size) {
107
memcpy(avctx->extradata + 2, pce_data, pce_size);
108
}
109
110
ctx->first_frame_done = 1;
111
}
112
113
*poutbuf = (uint8_t*) buf;
114
*poutbuf_size = buf_size;
115
116
return 0;
117
}
118
119
AVBitStreamFilter ff_aac_adtstoasc_bsf = {
120
.name = "aac_adtstoasc",
121
.priv_data_size = sizeof(AACBSFContext),
122
.filter = aac_adtstoasc_filter,
123
};
124
125