bbb
Posts: 55
Joined: Sat Jun 02, 2012 9:52 am

audio_encode suported codecs ?

Fri Jun 28, 2013 10:53 pm

Hi,

I am wondering, what HW audio codecs are supported on the videocore?

I am trying to create an MP3 encoder via OpenMAX and getting the following - strange the error message is with the input port and not the output port (MP3):
  • encode to idle...
    enabling port buffers for 161...
    enabling port buffers for 160...
    enabling port buffers for 160 failed!
with the following code:

Code: Select all

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

#include <bcm_host.h>
#include <ilclient.h>

int main(int argc, char **argv) {

	COMPONENT_T *audio_encode = NULL;
	OMX_BUFFERHEADERTYPE *buf;
	COMPONENT_T *list[2];
	ILCLIENT_T *client;
	OMX_ERRORTYPE r;
	OMX_PARAM_PORTDEFINITIONTYPE def;
	OMX_AUDIO_PARAM_PCMMODETYPE pcm;

	bcm_host_init();

	memset(list, 0, sizeof(list));

	if ((client = ilclient_init()) == NULL) {
		return -1;
	}

	if (OMX_Init() != OMX_ErrorNone) {
		fprintf(stderr,"OMX_Init() failed\n");
		ilclient_destroy(client);
		return -1;
	}

	// create audio_encode
	r = ilclient_create_component(client, &audio_encode, "audio_encode",
				      ILCLIENT_DISABLE_ALL_PORTS |
				      ILCLIENT_ENABLE_INPUT_BUFFERS |
				      ILCLIENT_ENABLE_OUTPUT_BUFFERS);

	if (r != 0) {
		fprintf(stderr,"ilclient_create_component() for video_encode failed with %x!\n", r);
		return -1;
	}

	list[0] = audio_encode;

/*****************************************************************************/
/* set input port */
/*****************************************************************************/
	memset(&def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
	def.nVersion.nVersion = OMX_VERSION;
	def.nPortIndex = 160;

	/* port def */
	if (OMX_GetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamPortDefinition, &def) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_GetParameter(OMX_IndexParamPortDefinition) for audio_encode port 160 failed!\n");
		return -1;
	}

	assert(def.format.audio.eEncoding == OMX_AUDIO_CodingPCM);

	if (OMX_SetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamPortDefinition, &def) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_SetParameter(OMX_IndexParamPortDefinition) for audio_encode port 160 failed!\n");
		return -1;
	}

	/* PCM params */
	memset(&pcm, 0, sizeof(OMX_AUDIO_PARAM_PCMMODETYPE));
	pcm.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
	pcm.nVersion.nVersion = OMX_VERSION;
	pcm.nPortIndex = 160;

	if (OMX_GetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamAudioPcm, &pcm) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_GetParameter(OMX_IndexParamAudioPcm) for audio_encode port 160 failed!\n");
		return -1;
	}

	/** musts from http://home.nouwen.name/RaspberryPi/documentation/ilcomponents/audio_encode.html */
	pcm.nBitPerSample = 16;
	pcm.eNumData = OMX_NumericalDataSigned;
	pcm.eEndian = OMX_EndianLittle;
	pcm.bInterleaved = OMX_TRUE;
	pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;

	//
	pcm.nChannels = 2;
	pcm.nSamplingRate = 48000;
	
	if (OMX_SetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamAudioPcm, &pcm) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_SetParameter(OMX_IndexParamAudioPcm) for audio_encode port 160 failed!\n");
		return -1;
	}

/*****************************************************************************/
/* set output port */
/*****************************************************************************/
	memset(&def, 0, sizeof(OMX_PARAM_PORTDEFINITIONTYPE));
	def.nSize = sizeof(OMX_PARAM_PORTDEFINITIONTYPE);
	def.nVersion.nVersion = OMX_VERSION;
	def.nPortIndex = 161;

	if (OMX_GetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamPortDefinition, &def) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_SetParameter(OMX_IndexParamPortDefinition) for audio_encode port 161 failed!\n");
		return -1;
	}

	def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;

	if (OMX_SetParameter(ILC_GET_HANDLE(audio_encode), OMX_IndexParamPortDefinition, &def) != OMX_ErrorNone) {
		fprintf(stderr, "OMX_SetParameter(OMX_IndexParamPortDefinition) for audio_encode port 161 failed!\n");
		return -1;
	}

/*****************************************************************************/
/* enable encoder */
/*****************************************************************************/

	fprintf(stderr, "encode to idle...\n");
	if (ilclient_change_component_state(audio_encode, OMX_StateIdle) == -1) {
		fprintf(stderr,"%s:%d: ilclient_change_component_state(audio_encode, OMX_StateIdle) failed",
		       __FUNCTION__, __LINE__);
	}

	fprintf(stderr, "enabling port buffers for 161...\n");
	if (ilclient_enable_port_buffers(audio_encode, 161, NULL, NULL, NULL) != 0) {
		fprintf(stderr, "enabling port buffers for 161 failed!\n");
		exit(1);
	}

	fprintf(stderr, "enabling port buffers for 160...\n");
	if (ilclient_enable_port_buffers(audio_encode, 160, NULL, NULL, NULL) != 0) {
		fprintf(stderr, "enabling port buffers for 160 failed!\n");
		exit(1);
	}

	fprintf(stderr, "encode to executing...\n");
	ilclient_change_component_state(audio_encode, OMX_StateExecuting);


/*****************************************************************************/
/* enter encode loop */
/*****************************************************************************/

	{
		char buffer [512];
		size_t read;
	
		// skip wave header - 44 bytes
		read = fread(buffer, 1, 44, stdin);
		fprintf(stderr,"read = %d", read);
		assert(read == 44);
	
		while(!feof(stdin)) {
			read = fread(buffer, 1, 512,  stdin);
			// TODO ..
			

			fwrite(buffer, read, 1, stdout);
		}
	}


	ilclient_cleanup_components(list);

	OMX_Deinit();

	ilclient_destroy(client);

	return 0;
}

sviborg
Posts: 8
Joined: Thu Jan 31, 2013 10:56 am

Re: audio_encode suported codecs ?

Mon Aug 19, 2013 9:03 pm

Hi, I'm also tried to use audio_encoder and got error "80001019 OMX_ErrorUnsupportedSetting" when enabling port 160 using "ilclient_enable_port". The port parameters are set like VMCS-X OpenMAX IL Components manual says.

So the question is does audio_encoder supports encoding from PCM to MP3/AAC/AMR?

Code: Select all

extern "C"
{
#include "bcm_host.h"
#include "ilclient.h"
}

#include <stdio.h>
//#include <stdlib.h>
//#include <string.h>
#include <pthread.h>

#include "OmxSoundEncoder.h"

static pthread_mutex_t _frame_mutex = PTHREAD_MUTEX_INITIALIZER;

static void* omxSoundEncoderThread(void *ptr);

void omxSoundEncoderStart(const char* filename)
{
	printf("pthread_create\n");
	pthread_t thread;
	pthread_create(&thread, NULL, &omxSoundEncoderThread, NULL);
}

void omxSoundEncoderEncode(void* buf, int size)
{
	pthread_mutex_lock(&_frame_mutex);

	pthread_mutex_unlock(&_frame_mutex);
}

static void* omxSoundEncoderThread(void *ptr)
{
	printf("enter omxSoundEncoderThread\n");

	const int BufSize = 8000;
	const int BufCount = 4;
	
	int port;
	OMX_INDEXTYPE index;

	int rc;
	OMX_ERRORTYPE omxerr;
	
	printf("ilclient_init\n");
	ILCLIENT_T* client = ilclient_init();
	if (!client)
	{
		printf("ilclient_init failed\n");
		return 0;
	}

	printf("OMX_Init\n");
	omxerr = OMX_Init();
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_Init failed: %X\n", omxerr);
		return 0;
	}

	printf("ilclient_create_component\n");
	COMPONENT_T* encoder = NULL;
	rc = ilclient_create_component(client, &encoder, "audio_encode",
		(ILCLIENT_CREATE_FLAGS_T)
		(ILCLIENT_DISABLE_ALL_PORTS |
		ILCLIENT_ENABLE_INPUT_BUFFERS |
		ILCLIENT_ENABLE_OUTPUT_BUFFERS));
	if (rc != 0)
	{
		printf("ilclient_create_component failed\n");
		return 0;
	}
	
	///////////////////////////////////////////////////////
	
	/* 
	 * Query / set the port parameter. Must be set to PCM audio. 
	 */

	port = 160;
	index = OMX_IndexParamPortDefinition;
	
	OMX_PARAM_PORTDEFINITIONTYPE def;
	memset(&def, 0, sizeof(def));
	
	def.nSize = sizeof(def);
	def.nVersion.nVersion = OMX_VERSION;
	def.nPortIndex = port;

	printf("OMX_GetParameter\n");
	omxerr = OMX_GetParameter(ILC_GET_HANDLE(encoder), index, &def);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_GetParameter failed: %X\n", omxerr);
		return 0;
	}

	def.eDomain = OMX_PortDomainAudio;
	def.format.audio.eEncoding = OMX_AUDIO_CodingPCM;
	def.nBufferSize = BufSize;
	def.nBufferCountActual = BufCount;
	def.nBufferCountMin = BufCount;
	
	printf("OMX_SetParameter\n");
	omxerr = OMX_SetParameter(ILC_GET_HANDLE(encoder), index, &def);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_SetParameter failed: %X\n", omxerr);
		return 0;
	}

	///////////////////////////////////////////////////////
	
	port = 160;
	index = OMX_IndexParamAudioPortFormat;
	
	OMX_AUDIO_PARAM_PORTFORMATTYPE fmt;
	memset(&fmt, 0, sizeof(fmt));
	
	fmt.nSize = sizeof(fmt);
	fmt.nVersion.nVersion = OMX_VERSION;
	fmt.nPortIndex = port;

	printf("OMX_GetParameter\n");
	omxerr = OMX_GetParameter(ILC_GET_HANDLE(encoder), index, &fmt);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_GetParameter failed: %X\n", omxerr);
		return 0;
	}

	fmt.eEncoding = OMX_AUDIO_CodingPCM;

	printf("OMX_SetParameter\n");
	omxerr = OMX_SetParameter(ILC_GET_HANDLE(encoder), index, &fmt);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_SetParameter failed: %X\n", omxerr);
		return 0;
	}
	
	///////////////////////////////////////////////////////
	
	/* 
	 * Query / set the port PCM format for the input port. 
	 * nChannels must be 1, 2, 4, or 8. 5.1 audio can be carried inside 8 channels, 
	 * with the last two channels advertise as blank. 
	 * nBitPerSample must be 16 or 32. 
	 * eNumData must be OMX_NumericalDataSigned. 
	 * eEndian must be OMX_EndianLittle. 
	 * bInterleaved must be OMX_TRUE. 
	 * ePCMMode must be OMX_AUDIO_PCMModeLinear. 
	 */

	port = 160;
	index = OMX_IndexParamAudioPcm;
	
	OMX_AUDIO_PARAM_PCMMODETYPE pcm;
	memset(&pcm, 0, sizeof(pcm));

	pcm.nSize = sizeof(pcm);
	pcm.nVersion.nVersion = OMX_VERSION;
	pcm.nPortIndex = port;
	
	printf("OMX_GetParameter\n");
	omxerr = OMX_GetParameter(ILC_GET_HANDLE(encoder), index, &pcm);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_GetParameter failed: %X\n", omxerr);
		return 0;
	}

	pcm.nChannels = 1;
	pcm.nBitPerSample = 16;
	pcm.eNumData = OMX_NumericalDataSigned;
	pcm.eEndian = OMX_EndianLittle;
	pcm.bInterleaved = OMX_TRUE;
	pcm.ePCMMode = OMX_AUDIO_PCMModeLinear;

	printf("OMX_SetParameter\n");
	omxerr = OMX_SetParameter(ILC_GET_HANDLE(encoder), index, &pcm);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_SetParameter failed: %X\n", omxerr);
		return 0;
	}
	
	///////////////////////////////////////////////////////
	
	/*
	 * Query / set the port parameter. The encoder to be used is specified by setting 
	 * the format.audio.eEncoding field. When encoding starts, if the maximum size 
	 * of encoded frame is larger than the nBufferSize value then the nBufferSize 
	 * is increased to this value and an OMX_EventPortSettingsChanged event is signalled. 
	 */

	port = 161;
	index = OMX_IndexParamPortDefinition;
	
	memset(&def, 0, sizeof(def));
	
	def.nSize = sizeof(def);
	def.nVersion.nVersion = OMX_VERSION;
	def.nPortIndex = port;

	printf("OMX_GetParameter\n");
	omxerr = OMX_GetParameter(ILC_GET_HANDLE(encoder), index, &def);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_GetParameter failed: %X\n", omxerr);
		return 0;
	}

	def.format.audio.eEncoding = OMX_AUDIO_CodingMP3;
	def.nBufferSize = BufSize;
	def.nBufferCountActual = BufCount;
	def.nBufferCountMin = BufCount;

	printf("OMX_SetParameter\n");
	omxerr = OMX_SetParameter(ILC_GET_HANDLE(encoder), index, &def);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_SetParameter failed: %X\n", omxerr);
		return 0;
	}
	
	///////////////////////////////////////////////////////
	
	/* 
	 * Query / set the MP3 parameters for the encoded bitstream. 
	 * Only the nBitRate and nChannels (must be 1 or 2) fields are considered; 
	 * other parameters are copied through from the PCM input port. 
	 */

	port = 161;
	index = OMX_IndexParamAudioMp3;
	
	OMX_AUDIO_PARAM_MP3TYPE mp3;
	memset(&mp3, 0, sizeof(mp3));
	
	mp3.nSize = sizeof(mp3);
	mp3.nVersion.nVersion = OMX_VERSION;
	mp3.nPortIndex = port;
	
	printf("OMX_GetParameter\n");
	omxerr = OMX_GetParameter(ILC_GET_HANDLE(encoder), index, &mp3);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_GetParameter failed: %X\n", omxerr);
		return 0;
	}

	mp3.nChannels = pcm.nChannels = 1;
	mp3.nBitRate = 128000;

	printf("OMX_SetParameter\n");
	omxerr = OMX_SetParameter(ILC_GET_HANDLE(encoder), index, &mp3);
	if (omxerr != OMX_ErrorNone)
	{
		printf("OMX_SetParameter failed: %X\n", omxerr);
		return 0;
	}
	
	///////////////////////////////////////////////////////

	printf("ilclient_change_component_state: idle\n");
	rc = ilclient_change_component_state(encoder, OMX_StateIdle);
	if (rc != 0)
	{
		printf("ilclient_change_component_state failed\n");
		return 0;
	}

	port = 160;
	printf("ilclient_enable_port: %d\n", port);
	ilclient_enable_port(encoder, port);

	printf("ilclient_enable_port_buffers: %d\n", port);
	rc = ilclient_enable_port_buffers(encoder, port, NULL, NULL, NULL);
	if (rc != 0)
	{
		printf("ilclient_enable_port_buffers failed: %d rc=%d\n", port, rc);
		return 0;
	}

	port = 161;
	printf("ilclient_enable_port_buffers: %d\n", port);
	rc = ilclient_enable_port_buffers(encoder, port, NULL, NULL, NULL);
	if (rc != 0)
	{
		printf("ilclient_enable_port_buffers failed: %d rc=%d\n", port, rc);
		return 0;
	}
	
	printf("ilclient_change_component_state: execute\n");
	rc = ilclient_change_component_state(encoder, OMX_StateExecuting);
	if (rc != 0)
	{
		printf("ilclient_change_component_state failed\n");
		return 0;
	}

	///////////////////////////////////////////////////////
	
	unsigned short dataBuf[BufSize];
	int dataLen = sizeof(dataBuf);
	
	unsigned short outBuf[BufSize];
	int outLen = sizeof(outBuf);

	do
	{
		OMX_BUFFERHEADERTYPE* buf = ilclient_get_input_buffer(encoder, 160, 1);
		if (!buf)
		{
			printf("ilclient_get_input_buffer failed\n");
			return 0;
		}

		memcpy(buf->pBuffer, dataBuf, dataLen);
		buf->nFilledLen = dataLen;
		
		omxerr = OMX_EmptyThisBuffer(ILC_GET_HANDLE(encoder), buf);
		if (omxerr != OMX_ErrorNone)
		{
			printf("OMX_EmptyThisBuffer failed\n");
			return 0;
		}
		
		OMX_BUFFERHEADERTYPE* out = ilclient_get_output_buffer(encoder, 161, 1);
		if (!buf)
		{
			printf("ilclient_get_output_buffer failed\n");
			return 0;
		}
		
		omxerr = OMX_FillThisBuffer(ILC_GET_HANDLE(encoder), out);
		if (omxerr != OMX_ErrorNone)
		{
			printf("OMX_FillThisBuffer failed\n");
			return 0;
		}
		
		printf("encoded buf=%X len=%d\n", out->pBuffer, out->nFilledLen);
		
		memcpy(outBuf, out->pBuffer, out->nFilledLen);
	}
	while (1);

	///////////////////////////////////////////////////////
	
	//ilclient_disable_port_buffers(encoder, 200, NULL, NULL, NULL);
	//ilclient_disable_port_buffers(encoder, 201, NULL, NULL, NULL);

	//ilclient_state_transition(list, OMX_StateIdle);
	//ilclient_state_transition(list, OMX_StateLoaded);

	//ilclient_cleanup_components(list);

	//OMX_Deinit();

	//ilclient_destroy(client);
	
	return 0;
}

darkyp
Posts: 6
Joined: Tue Apr 28, 2015 5:53 am

Re: audio_encode suported codecs ?

Tue May 19, 2015 12:35 pm

Same problem here. Any news / information on this? After setting input port eEncoding and PCMMode as per the docs, enabling the port results in 0x80000019. Using the same code on the audio_render input port results in no error.

Return to “C/C++”