Refactor channel element configuration and mapping code into its own function

to allow reuse

Originally committed as revision 20069 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
Robert Swain 2009-09-28 15:37:18 +00:00
parent 2309923c5c
commit 754ff9a795
1 changed files with 39 additions and 23 deletions

View File

@ -152,6 +152,37 @@ static ChannelElement *get_che(AACContext *ac, int type, int elem_id)
}
}
/**
* Check for the channel element in the current channel position configuration.
* If it exists, make sure the appropriate element is allocated and map the
* channel order to match the internal FFmpeg channel layout.
*
* @param che_pos current channel position configuration
* @param type channel element type
* @param id channel element id
* @param channels count of the number of channels in the configuration
*
* @return Returns error status. 0 - OK, !0 - error
*/
static int che_configure(AACContext *ac,
enum ChannelPosition che_pos[4][MAX_ELEM_ID],
int type, int id,
int *channels)
{
if (che_pos[type][id]) {
if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
if (type != TYPE_CCE) {
ac->output_data[(*channels)++] = ac->che[type][id]->ch[0].ret;
if (type == TYPE_CPE) {
ac->output_data[(*channels)++] = ac->che[type][id]->ch[1].ret;
}
}
} else
av_freep(&ac->che[type][id]);
return 0;
}
/**
* Configure output channel order based on the current program configuration element.
*
@ -166,23 +197,17 @@ static int output_configure(AACContext *ac,
int channel_config)
{
AVCodecContext *avctx = ac->avccontext;
int i, type, channels = 0;
int i, type, channels = 0, ret;
memcpy(che_pos, new_che_pos, 4 * MAX_ELEM_ID * sizeof(new_che_pos[0][0]));
if (channel_config) {
for (i = 0; i < tags_per_config[channel_config]; i++) {
const int id = aac_channel_layout_map[channel_config - 1][i][1];
type = aac_channel_layout_map[channel_config - 1][i][0];
if (!ac->che[type][id] && !(ac->che[type][id] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
if (type != TYPE_CCE) {
ac->output_data[channels++] = ac->che[type][id]->ch[0].ret;
if (type == TYPE_CPE)
ac->output_data[channels++] = ac->che[type][id]->ch[1].ret;
}
if ((ret = che_configure(ac, che_pos,
aac_channel_layout_map[channel_config - 1][i][0],
aac_channel_layout_map[channel_config - 1][i][1],
&channels)))
return ret;
}
memset(ac->tag_che_map, 0, 4 * MAX_ELEM_ID * sizeof(ac->che[0][0]));
@ -201,17 +226,8 @@ static int output_configure(AACContext *ac,
for (i = 0; i < MAX_ELEM_ID; i++) {
for (type = 0; type < 4; type++) {
if (che_pos[type][i]) {
if (!ac->che[type][i] && !(ac->che[type][i] = av_mallocz(sizeof(ChannelElement))))
return AVERROR(ENOMEM);
if (type != TYPE_CCE) {
ac->output_data[channels++] = ac->che[type][i]->ch[0].ret;
if (type == TYPE_CPE) {
ac->output_data[channels++] = ac->che[type][i]->ch[1].ret;
}
}
} else
av_freep(&ac->che[type][i]);
if ((ret = che_configure(ac, che_pos, type, i, &channels)))
return ret;
}
}