예제 #1
0
int static decodeFrame(AVCodecContext* codecCtx, uint8_t* buffer,
                       int bufferSize, packetQueue* queue)
{
	static AVPacket* packet = NULL;
	static int packetSize = 0;
	static uint8_t* packetData = NULL;

	//Get a packet.
	if(packetSize == 0)
	{
		packet = queue->get();
		if(!packet)
			return -1;
		packetSize = packet->size;
		packetData = packet->data;
	}

	int dataSize = bufferSize;
	int framesRead = avcodec_decode_audio2(codecCtx, (int16_t*)buffer,
	                                       &dataSize, packetData, packetSize);

	if(framesRead < 0)
	{
		//Skip this frame if we have an error.
		packetSize = 0;
		return 0;
	}

	packetSize -= framesRead;
	packetData -= framesRead;

	return dataSize;
}
예제 #2
0
파일: ffmpeg.c 프로젝트: Emisense/eTracks
/* Decode one audio frame and returns its uncompressed size */
static int audio_decode_frame(priv_t * ffmpeg, uint8_t *audio_buf, int buf_size)
{
  AVPacket *pkt = &ffmpeg->audio_pkt;
  int len1, data_size;

  for (;;) {
    /* NOTE: the audio packet can contain several frames */
    while (ffmpeg->audio_pkt_size > 0) {
      data_size = buf_size;
      len1 = avcodec_decode_audio2(ffmpeg->audio_st->codec,
                                   (int16_t *)audio_buf, &data_size,
                                   ffmpeg->audio_pkt_data, ffmpeg->audio_pkt_size);
      if (len1 < 0) {
        /* if error, we skip the frame */
        ffmpeg->audio_pkt_size = 0;
        break;
      }

      ffmpeg->audio_pkt_data += len1;
      ffmpeg->audio_pkt_size -= len1;
      if (data_size <= 0)
        continue;
      return data_size;
    }

    ffmpeg->audio_pkt_data = pkt->data;
    ffmpeg->audio_pkt_size = pkt->size;
  }
}
예제 #3
0
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size)
{
    static AVPacket pkt;
    static uint8_t *audio_pkt_data = NULL;
    static int audio_pkt_size = 0;
    int len1, data_size;
    for(;;)
    {
        if(packet_queue_get(audioq, &pkt, 1) < 0)
        {
            return -1;
        }
        audio_pkt_data = pkt.data;
        audio_pkt_size = pkt.size;
        while(audio_pkt_size > 0)
        {
            data_size = buf_size;
            len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size,audio_pkt_data, audio_pkt_size);
            if(len1 < 0)
            {
                audio_pkt_size = 0;
                break;
            }
            audio_pkt_data += len1;
            audio_pkt_size -= len1;
            if(data_size <= 0)
            {
                continue;
            }
            return data_size;
        }
        if(pkt.data)
            av_free_packet(&pkt);
   }
}
예제 #4
0
Omm::AvStream::Frame*
FFmpegStreamInfo::decodeAudioFrame(Omm::AvStream::Frame* pFrame)
{
    _pDecodedAudioFrame->_size = _maxDecodedAudioFrameSize;

    uint8_t* inBuffer = (uint8_t*)pFrame->data();
    int inBufferSize = pFrame->size();
    // TODO: does this while loop work for uncompressed packets ?
    // (it's only needed for e.g. .wav, where on packet contains multiple uncompressed frames
    while(inBufferSize > 0) {
        LOG(ffmpeg, trace, "ffmpeg::avcodec_decode_audio2() ...");
        int bytesConsumed = avcodec_decode_audio2(_pAvCodecContext,
            (int16_t*)_pDecodedAudioFrame->_data, &_pDecodedAudioFrame->_size,
            inBuffer, inBufferSize);

        LOG(ffmpeg, debug, "ffmpeg::avcodec_decode_audio2() frame size: " + Poco::NumberFormatter::format(inBufferSize) + ", bytes consumed: " + Poco::NumberFormatter::format(bytesConsumed) + ", decoded size: " +\
            Poco::NumberFormatter::format(_pDecodedAudioFrame->size())
            );

        if (bytesConsumed < 0 || _pDecodedAudioFrame->size() == 0) {
            LOGNS(Omm::AvStream, avstream, warning, "decoding audio frame in stream " + getName() + " failed, discarding frame.");
            delete pFrame;
            return 0;
        }
        inBuffer += bytesConsumed;
        inBufferSize -= bytesConsumed;
    }
    return _pDecodedAudioFrame;
}
예제 #5
0
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size, double *pts_ptr) {

  int len1, data_size, n;
  AVPacket *pkt = &is->audio_pkt;
  double pts;

  for(;;) {
    while(is->audio_pkt_size > 0) {
      data_size = buf_size;
      len1 = avcodec_decode_audio2(is->audio_st->codec, 
				   (int16_t *)audio_buf, &data_size, 
				   is->audio_pkt_data, is->audio_pkt_size);
      if(len1 < 0) {
	/* if error, skip frame */
	is->audio_pkt_size = 0;
	break;
      }
      is->audio_pkt_data += len1;
      is->audio_pkt_size -= len1;
      if(data_size <= 0) {
	/* No data yet, get more frames */
	continue;
      }
      pts = is->audio_clock;
      *pts_ptr = pts;
      n = 2 * is->audio_st->codec->channels;
      is->audio_clock += (double)data_size /
	(double)(n * is->audio_st->codec->sample_rate);

      /* We have data, return it and come back for more later */
      return data_size;
    }
    if(pkt->data)
      av_free_packet(pkt);

    if(is->quit) {
      return -1;
    }
    /* next packet */
    if(packet_queue_get(&is->audioq, pkt, 1) < 0) {
      return -1;
    }
    if(pkt->data == flush_pkt.data) {
      avcodec_flush_buffers(is->audio_st->codec);
      continue;
    }
    is->audio_pkt_data = pkt->data;
    is->audio_pkt_size = pkt->size;
    /* if update, update the audio clock w/pts */
    if(pkt->pts != AV_NOPTS_VALUE) {
      is->audio_clock = av_q2d(is->audio_st->time_base)*pkt->pts;
    }
  }
}
            void decodeFrame() throw(PacketDecodeException)
            {
                if (!hasPacket())
                    throw PacketDecodeException();
                
                int dataSize = sampleBufferAlloc;
                int used = 
                #if (LIBAVCODEC_VERSION_MAJOR >= 53)
                    avcodec_decode_audio3(
                        pCodecCtx,
                        (int16_t*)sampleBufferAligned, &dataSize,
                        &packet);
                #else
                    avcodec_decode_audio2(
                        pCodecCtx,
                        (int16_t*)sampleBufferAligned, &dataSize,
                        packetBuffer, packetBufferSize);
                #endif
                
                if (used < 0)
                    throw PacketDecodeException();
                
                #if (LIBAVCODEC_VERSION_MAJOR >= 53)
                
                if ((size_t)used > packet.size)
                    used = packet.size;

                (char*&)(packet.data) += used;
                packet.size -= used;
                
                #else
                
                if ((size_t)used > packetBufferSize)
                    used = packetBufferSize;

                (char*&)packetBuffer += used;
                packetBufferSize -= used;
                
                #endif
                
                if (dataSize < 0)
                    dataSize = 0;

                sampleBuffer = sampleBufferAligned;
                sampleBufferStart += sampleBufferSize;
                sampleBufferSize = dataSize / sampleSize;
                
                if (sampleBufferStart + sampleBufferSize > streamSize)
                    streamSize = sampleBufferStart + sampleBufferSize;
            }
예제 #7
0
int CFFMPEGLoader::ReadAudioData(unsigned char *buf, const UINT &buf_size) {
    int len1, data_size;

    for(; iPKTAudioLength>0;) {

        while(audio_pkt_size > 0 && audio_pkt_data) {
            data_size = buf_size;
            bLock=true;
            len1 = avcodec_decode_audio2(pACodecCon, (int16_t *)buf, &data_size,
                                         audio_pkt_data, audio_pkt_size);
            bLock=false;
            if(len1 < 0) {
                /* if error, skip frame */
                audio_pkt_size = 0;
                break;
            }

            audio_pkt_data += len1;
            audio_pkt_size -= len1;

            if(data_size <= 0) {
                /* No data yet, get more frames */
                continue;
            }

            /* We have data, return it and come back for more later */
            return data_size;
        }

        bLock=true;
        if(pktLastAudio[0].data)
            av_free_packet(&pktLastAudio[0]);

        iPKTAudioLength--;
        for(UINT i=0; i<iPKTAudioLength; i++)
            pktLastAudio[i]=pktLastAudio[i+1];
        pktLastAudio[iPKTAudioLength].data=NULL;
        bLock=false;

        if(iPKTAudioLength<1) {
            return -1;
        }
        audio_pkt_data = pktLastAudio[0].data;
        audio_pkt_size = pktLastAudio[0].size;
    }

    return -1;
}
예제 #8
0
파일: demo_YUV.c 프로젝트: taoanran/ffmpeg
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size)  
{  
    static AVPacket pkt;  
    static uint8_t *audio_pkt_data = NULL;  
    static int audio_pkt_size = 0;  
    int len1, data_size;  
	AVFrame *pFrame = 0;
	pFrame = avcodec_alloc_frame();

	int got;
    for(;;)  
    {  
        while(audio_pkt_size > 0)  
        {  
            data_size = buf_size;  
			avcodec_decode_audio4(aCodecCtx, pFrame, &got, &packet);
            len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size, audio_pkt_data, audio_pkt_size);  
            if(len1 < 0)  
            { /* if error, skip frame */  
                audio_pkt_size = 0;  
                break;  
            }  
            audio_pkt_data += len1;  
            audio_pkt_size -= len1;  
            if(data_size <= 0)  
            { /* No data yet, get more frames */  
                continue;  
            } /* We have data, return it and come back for more later */  
            return data_size;  
        }  
        if(pkt.data)  
            av_free_packet(&pkt);  
        if(quit)  
        {  
            return -1;  
        }  
        if(packet_queue_get(&audioq, &pkt, 1) < 0)  
        {  
            return -1;  
        }  
        audio_pkt_data = pkt.data;  
        audio_pkt_size = pkt.size;  
    }  
}  
예제 #9
0
static int decode_audio(AVCodecContext *avctx, int16_t *samples,
                         int *frame_size_ptr,
                         const uint8_t *buf, int buf_size)
{
#if LIBAVCODEC_VERSION_MAJOR >= 53 || (LIBAVCODEC_VERSION_MAJOR==52 && LIBAVCODEC_VERSION_MINOR>=32)

    // following code segment copied from ffmpeg's avcodec_decode_audio2()
    // implementation to avoid warnings about deprecated function usage.
    AVPacket avpkt;
    av_init_packet(&avpkt);
    avpkt.data = const_cast<uint8_t *>(buf);
    avpkt.size = buf_size;

    return avcodec_decode_audio3(avctx, samples, frame_size_ptr, &avpkt);
#else
    // fallback for older versions of ffmpeg that don't have avcodec_decode_audio3.
    return avcodec_decode_audio2(avctx, samples, frame_size_ptr, buf, buf_size);
#endif
}
예제 #10
0
quint8 *DataSource::decodeAudio(AVCodecContext *codecCtx, AVPacket *packet, int *size) {
    uint8_t *sampleBuf = NULL;
    int decodeSize = 0;
    *size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
    sampleBuf = (uint8_t *)malloc(AVCODEC_MAX_AUDIO_FRAME_SIZE * sizeof(uint8_t));
    decodeSize = avcodec_decode_audio2(codecCtx,
                                  (int16_t *)sampleBuf,
                                  size,
                                  packet->data,
                                  packet->size);

    if (*size < 0) {
        free(sampleBuf);
        DPRINT("can ont decode data.");
        return NULL;
    }

    return sampleBuf;
}
예제 #11
0
int audio_decode_frame(AVCodecContext *aCodecCtx, uint8_t *audio_buf, int buf_size) {

    static AVPacket pkt;
    static uint8_t *audio_pkt_data = NULL;
    static int audio_pkt_size = 0;
	// len1: number of bytes used to decompress
	// data_size: out put buffer size
    int len1, data_size;

    for(;;) {
        while(audio_pkt_size > 0) {
            data_size = buf_size;
            // @see http://dranger.com/ffmpeg/functions.html#avcodec_decode_audio2
            len1 = avcodec_decode_audio2(aCodecCtx, (int16_t *)audio_buf, &data_size,
                                         audio_pkt_data, audio_pkt_size);
            if(len1 < 0) {
                /* if error, skip frame */
                audio_pkt_size = 0;
                break;
            }
            audio_pkt_data += len1;
            audio_pkt_size -= len1;
            if(data_size <= 0) {
                /* No data yet, get more frames */
                continue;
            }
            /* We have data, return it and come back for more later */
            return data_size;
        }
        if(pkt.data)
            av_free_packet(&pkt);

        if(quit) {
            return -1;
        }

        if(packet_queue_get(&audioq, &pkt, 1) < 0) {
            return -1;
        }
        audio_pkt_data = pkt.data;
        audio_pkt_size = pkt.size;
    }
}
예제 #12
0
int VideoLayer::decode_audio_packet(int *data_size) {
  int datasize, res;

  datasize = AVCODEC_MAX_AUDIO_FRAME_SIZE; //+ FF_INPUT_BUFFER_PADDING_SIZE;
#if LIBAVCODEC_VERSION_MAJOR < 53
  res = avcodec_decode_audio2(audio_codec_ctx, (int16_t *)audio_buf,
			      &datasize, pkt.data, pkt.size);
#else
  res = avcodec_decode_audio3(audio_codec_ctx, (int16_t *)audio_buf,
			      &datasize, &pkt);
#endif

  if (data_size) *data_size = datasize; 
  
  if(res < 0) {
    /* if error, skip frame */
    pkt.size = 0;
    return 0;
  }
  /* We have data, return it and come back for more later */
  return res;
}
int audio_decode_frame(VideoState *is, uint8_t *audio_buf, int buf_size) {

  int len1, data_size;
  AVPacket *pkt = &is->audio_pkt;

  for(;;) {
    while(is->audio_pkt_size > 0) {
      data_size = buf_size;
      len1 = avcodec_decode_audio2(is->audio_st->codec, 
				  (int16_t *)audio_buf, &data_size, 
				  is->audio_pkt_data, is->audio_pkt_size);
      if(len1 < 0) {
	/* if error, skip frame */
	is->audio_pkt_size = 0;
	break;
      }
      is->audio_pkt_data += len1;
      is->audio_pkt_size -= len1;
      if(data_size <= 0) {
	/* No data yet, get more frames */
	continue;
      }
      /* We have data, return it and come back for more later */
      return data_size;
    }
    if(pkt->data)
      av_free_packet(pkt);

    if(is->quit) {
      return -1;
    }
    /* next packet */
    if(packet_queue_get(&is->audioq, pkt, 1) < 0) {
      return -1;
    }
    is->audio_pkt_data = pkt->data;
    is->audio_pkt_size = pkt->size;
  }
}
예제 #14
0
파일: IoAVCodec.c 프로젝트: BMeph/io
int IoAVCodec_decodeAudioPacket(IoAVCodec *self, AVCodecContext *c, uint8_t *inbuf, size_t size)
{
	UArray  *outba  = IoSeq_rawUArray(DATA(self)->outputBuffer);
	uint8_t *outbuf = DATA(self)->audioOutBuffer;

	//UArray_setItemType_(outba, CTYPE_float32_t);

	while (size > 0)
	{
		int outSize;
		int len = avcodec_decode_audio2(c, (int16_t *)outbuf, &outSize, inbuf, size);

		if (len < 0)
		{
			printf("Error while decoding audio packet\n");
			return -1;
		}

		if (outSize > 0)
		{
			// if a frame has been decoded, output it
			// convert short ints to floats

			size_t sampleCount = outSize / c->channels;
			size_t oldSize = UArray_size(outba);
			//UArray_setSize_(outba, oldSize + sampleCount); // knows it's a float32 array
			UArray_setSize_(outba, oldSize + sampleCount * sizeof(float)); // knows it's a float32 array

			IoAVCodec_ConvertShortToFloat((short *)outbuf, (float *)(UArray_bytes(outba) + oldSize), sampleCount);
		}

		size -= len;
		inbuf += len;
	}

	return 0;
}
예제 #15
0
파일: ffmpeg.c 프로젝트: gitkaste/moc
static int ffmpeg_decode (void *prv_data, char *buf, int buf_len,
		struct sound_params *sound_params)
{
	struct ffmpeg_data *data = (struct ffmpeg_data *)prv_data;
	int ret;
	int data_size;
	AVPacket pkt, pkt_tmp;
	uint8_t *pkt_data;
	int pkt_size = 0;
	int filled = 0;

	/* The sample buffer should be 16 byte aligned (because SSE), a segmentation
	 * fault may occur otherwise.
	 * 
	 * See: avcodec.h in ffmpeg
	 */
	char avbuf[(AVCODEC_MAX_AUDIO_FRAME_SIZE * 3) / 2] __attribute__((aligned(16)));

	decoder_error_clear (&data->error);

	sound_params->channels = data->enc->channels;
	sound_params->rate = data->enc->sample_rate;
	sound_params->fmt = SFMT_S16 | SFMT_NE;
	
	if (data->remain_buf) {
		int to_copy = MIN (buf_len, data->remain_buf_len);
		
		debug ("Copying %d bytes from the remain buf", to_copy);
		
		memcpy (buf, data->remain_buf, to_copy);
		
		if (to_copy < data->remain_buf_len) {
			memmove (data->remain_buf, data->remain_buf + to_copy,
					data->remain_buf_len - to_copy);
			data->remain_buf_len -= to_copy;
		}
		else {
			debug ("Remain buf is now empty");
			free (data->remain_buf);
			data->remain_buf = NULL;
			data->remain_buf_len = 0;
		}

		return to_copy;
	}

	do {
		ret = av_read_frame (data->ic, &pkt);
		if (ret < 0)
			return 0;

		memcpy(&pkt_tmp, &pkt, sizeof(pkt));
		pkt_data = pkt.data;
		pkt_size = pkt.size;
		debug ("Got %dB packet", pkt_size);
		
		while (pkt_size) {
			int len;

#if LIBAVCODEC_VERSION_INT >= ((52<<16)+(26<<8)+0)
			data_size = sizeof (avbuf);
			len = avcodec_decode_audio3 (data->enc, (int16_t *)avbuf,
					&data_size, &pkt);
#elif LIBAVCODEC_VERSION_INT >= ((51<<16)+(50<<8)+0)
			data_size = sizeof (avbuf);
			len = avcodec_decode_audio2 (data->enc, (int16_t *)avbuf,
					&data_size, pkt_data, pkt_size);
#else
			len = avcodec_decode_audio (data->enc, (int16_t *)avbuf,
					&data_size, pkt_data, pkt_size);
#endif

			debug ("Decoded %dB", data_size);

			if (len < 0)  {
				/* skip frame */
				decoder_error (&data->error, ERROR_STREAM, 0,
						"Error in the stream!");
				break;
			}

			pkt_data += len;
			pkt_size -= len;

			if (buf_len) {
				int to_copy = MIN (data_size, buf_len);
			
				memcpy (buf, avbuf, to_copy);

				buf += to_copy;
				filled += to_copy;
				buf_len -= to_copy;

				debug ("Copying %dB (%dB filled)", to_copy,
						filled);

				if (to_copy < data_size)
					put_in_remain_buf (data,
							avbuf + to_copy,
							data_size - to_copy);
			}
			else if (data_size)
				add_to_remain_buf (data, avbuf, data_size);
			
		}
	} while (!filled);
	
	/* 2.0 - 16bit/sample*/
	data->bitrate = pkt.size * 8 / ((filled + data->remain_buf_len) / 2.0 /
			sound_params->channels / sound_params->rate) / 1000;

	av_free_packet (&pkt_tmp);
	
	return filled;
}
예제 #16
0
int FileFFMPEG::read_samples(double *buffer, int64_t len)
{
	const int debug = 0;
	int error = 0;
	ffmpeg_lock->lock("FileFFMPEG::read_samples");

	if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__);
// Compute stream & stream channel from global channel
	int audio_channel = file->current_channel;
	int audio_index = -1;
	FileFFMPEGStream *stream = 0;
	for(int i = 0; i < audio_streams.size(); i++)
	{
		if(audio_channel < audio_streams.get(i)->channels)
		{
			stream = audio_streams.get(i);
			audio_index = stream->index;
			break;
		}
		audio_channel -= audio_streams.get(i)->channels;
	}
	if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__);

	AVStream *ffmpeg_stream = ((AVFormatContext*)stream->ffmpeg_file_context)->streams[stream->index];
	AVCodecContext *decoder_context = ffmpeg_stream->codec;

	stream->update_pcm_history(file->current_sample, len);
	if(debug) printf("FileFFMPEG::read_samples %d len=%d\n", __LINE__, (int)len);



	if(debug) printf("FileFFMPEG::read_samples %d decode_start=%lld decode_end=%lld\n",
		__LINE__,
		(long long)stream->decode_start,
		(long long)stream->decode_end);

// Seek occurred
	if(stream->decode_start != stream->decode_end)
	{
		int64_t timestamp = (int64_t)((double)file->current_sample * 
			ffmpeg_stream->time_base.den /
			ffmpeg_stream->time_base.num /
			asset->sample_rate);
// Want to seek to the nearest keyframe and read up to the current frame
// but ffmpeg doesn't support that kind of precision.
// Also, basing all the seeking on the same stream seems to be required for synchronization.
		if(debug) printf("FileFFMPEG::read_samples %d\n",
			__LINE__);
		av_seek_frame((AVFormatContext*)stream->ffmpeg_file_context, 
			/* stream->index */ 0, 
			timestamp, 
			AVSEEK_FLAG_ANY);
		if(debug) printf("FileFFMPEG::read_samples %d\n",
			__LINE__);
		stream->current_sample = file->current_sample;
		stream->decode_end = stream->decode_start;
	}

	if(debug) printf("FileFFMPEG::read_samples %d stream->decode_len=%d\n", 
		__LINE__,
		(int)stream->decode_len);




	int got_it = 0;
	int accumulation = 0;
// Read frames until the requested range is decoded.
	while(accumulation < stream->decode_len && !error)
	{
//printf("FileFFMPEG::read_samples %d accumulation=%d\n", __LINE__, accumulation);
		AVPacket packet;
		error = av_read_frame((AVFormatContext*)stream->ffmpeg_file_context, 
			&packet);
		unsigned char *packet_ptr = packet.data;
		int packet_len = packet.size;
		if(debug) printf("FileFFMPEG::read_samples %d error=%d packet_len=%d\n", 
		__LINE__, 
		error, 
		packet_len);

		if(packet.stream_index == stream->index)
		{
			while(packet_len > 0 && !error)
			{
				int data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
                if(!ffmpeg_samples) ffmpeg_samples = (short*)realloc(ffmpeg_samples, data_size);
if(debug) printf("FileFFMPEG::read_samples %d decoder_context=%p ffmpeg_samples=%p data_size=%d packet.size=%d packet.data=%p codec_id=%d\n", 
__LINE__, 
decoder_context,
ffmpeg_samples,
data_size,
packet_len,
packet_ptr,
decoder_context->codec_id);
//av_log_set_level(AV_LOG_DEBUG);


#if 1
				int bytes_decoded = avcodec_decode_audio2(decoder_context, 
					ffmpeg_samples, 
					&data_size,
                    packet_ptr, 
					packet_len);
#else
				int bytes_decoded = avcodec_decode_audio(decoder_context, 
					ffmpeg_samples, 
					&data_size,
                    packet_ptr, 
					packet_len);
#endif


if(debug) PRINT_TRACE
//				if(bytes_decoded < 0) error = 1;
				if(bytes_decoded == -1) error = 1;
				packet_ptr += bytes_decoded;
				packet_len -= bytes_decoded;
if(debug) printf("FileFFMPEG::read_samples %d bytes_decoded=%d data_size=%d\n", 
__LINE__, 
bytes_decoded,
data_size);
//				if(data_size <= 0)
//					break;
				int samples_decoded = data_size / 
					stream->channels / 
					sizeof(short);
// Transfer decoded samples to ring buffer
				stream->append_history(ffmpeg_samples, samples_decoded);
// static FILE *fd = 0;
// if(!fd) fd = fopen("/tmp/test.pcm", "w");
// fwrite(ffmpeg_samples, data_size, 1, fd);
				accumulation += samples_decoded;
			}
		}
		if(debug) PRINT_TRACE
		
		av_free_packet(&packet);
	}
	if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__);

	stream->read_history(buffer, 
		file->current_sample, 
		audio_channel,
		len);
	if(debug) printf("FileFFMPEG::read_samples %d\n", __LINE__);

	if(debug) printf("FileFFMPEG::read_samples %d %d\n", __LINE__, error);
	stream->current_sample += len;
	ffmpeg_lock->unlock();
	return error;
}
예제 #17
0
int main(int argc, char **argv) {
	AVFormatContext *formatCtx = NULL;
	AVCodecContext *codecCtx = NULL;
	AVCodec *codec = NULL;
	AVPacket packet;

	uint8_t sample_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE] = {0};
	int buf_size = sizeof(sample_buf);
	int decodec_size = 0;
	int len = 0;
	char **input_files = NULL;
	int opt = 0;
	int count = 0;
	int i = 0;

	int error = 0;
	pa_simple *ps = NULL;	
	pa_sample_spec pss= {0};

	while ((opt = getopt(argc, argv, "d:i:")) != -1) {
		switch (opt) {
		case 'd':
			count = iter_dir(&input_files, optarg);
			chdir(optarg);
			break;
		case 'i':
			input_files = (char **)malloc(sizeof(char **));
			input_files[0] = (char *)malloc(strlen(optarg) + 1);
			memset(input_files[0], 0, strlen(optarg + 1));
			strcpy(input_files[0], optarg);
			count = 1;
			break;
		default:
			printf("mp3player usage:\n"
				"\t-d [directory] set input directory\n"
				"\t-i [file] set input file\n");
			return -1;
		}
	}

	av_register_all();
	
	for (i = 0; i < count; i++) {
	    printf("play audio file: %s\n", input_files[i]);
	    if (av_open_input_file(&formatCtx, 
		    input_files[i], 
		    NULL, 
		    0, 
		    NULL) != 0) 
	    {
		    fprintf(stderr, "can not open input file.\n");
		    return -1;
	    }

	    if (av_find_stream_info(formatCtx) < 0) {
		    fprintf(stderr, "can not find stream info.\n");
		    return -1;
	    }

	    dump_format(formatCtx, 0, input_files[i], 0);

	    printf("streams: %d\n", formatCtx->nb_streams);
	    codecCtx = formatCtx->streams[0]->codec;	

	    switch (codecCtx->sample_fmt) {
	    case SAMPLE_FMT_S16:
		    pss.format = PA_SAMPLE_S16LE;
		    break;
	    case SAMPLE_FMT_U8:
		    pss.format = PA_SAMPLE_U8;
		    break;
	    default:
		    fprintf(stderr, "can not support this format for dsp.\n");	
		    return -1;
	    }

		pss.channels = codecCtx->channels;

	    pss.rate = codecCtx->sample_rate;

		printf("channels: %d\n", pss.channels);
		printf("rate: %d\n", pss.rate);
		printf("format: %d\n", pss.format);

		ps = pa_simple_new(NULL, 
				input_files[i],
				PA_STREAM_PLAYBACK,
				NULL,
				"Music",
				&pss,
				NULL,
				NULL,
				&error);
		
		if (ps == NULL) {
			fprintf(stderr, "can not get new pulase stream: %s\n", pa_strerror(error));
			return -1;
		}

	    codec = avcodec_find_decoder(codecCtx->codec_id);

	    if (codec == NULL) {
		    fprintf(stderr, "can not find codec.\n");
		    return -1;
	    }

	    if (avcodec_open(codecCtx, codec) < 0) {
		    fprintf(stderr, "can not open codec.\n");
		    return -1;
	    }

	    while (av_read_frame(formatCtx, &packet) >= 0) {
		    buf_size = AVCODEC_MAX_AUDIO_FRAME_SIZE;
		    decodec_size = avcodec_decode_audio2(codecCtx, 
			    (int16_t *)sample_buf, 
			    &buf_size, 
			    packet.data, packet.size);

		    if (decodec_size < 0) {
			    fprintf(stderr, "can not decode\n");
			    return -1;
		    }

			len = pa_simple_write(ps, sample_buf, buf_size, &error);

		    if (len < 0) {
			    fprintf(stderr, "pa_sample_write() failed: %s\n", pa_strerror(error));
			    return -1;
		    }
		
		    av_free_packet(&packet);
	    }

	    avcodec_close(codecCtx);
	    av_close_input_file(formatCtx);
		pa_simple_free(ps);
	}

	for (i = 0; i < count; i++) {
		free(input_files[count]);
	}

	free(input_files);

	return 0;
}
예제 #18
0
uint8_t ADM_AudiocodecWMA::run(uint8_t *inptr, uint32_t nbIn, float *outptr, uint32_t *nbOut)
{
int out=0;
int max=0,pout=0;
int16_t *run16;
int nbChunk;

        *nbOut=0;
        // Shrink
        if(_head && (_tail+nbIn)*3>ADMWA_BUF*2)
        {
            memmove(_buffer,_buffer+_head,_tail-_head);
            _tail-=_head;
            _head=0;
        }
        //
        ADM_assert(nbIn+_tail<ADMWA_BUF);
        memcpy(_buffer+_tail,inptr,nbIn);
        _tail+=nbIn;
        while(_tail-_head>=_blockalign)
        {
          nbChunk=(_tail-_head)/_blockalign;
          pout=SCRATCH_PAD_SIZE;
          out=avcodec_decode_audio2(_context,(int16_t *)scratchPad,
                                   &pout,_buffer+_head,nbChunk*_blockalign);
                
          if(out<0)
          {
            printf( " *** WMA decoding error (%u)***\n",_blockalign);
            _head+=1; // Try skipping some bytes
            continue;
          }
          if(pout>=SCRATCH_PAD_SIZE)
          {
            printf("Produced : %u, buffer %u,in%u\n",pout,SCRATCH_PAD_SIZE,_tail-_head);
            ADM_assert(0); 
          }
          if(_context->codec_id == CODEC_ID_NELLYMOSER)
          { // Hack, it returns inconsistent size
            out=nbChunk*_blockalign;
          }
          _head+=out; // consumed bytes
          pout>>=1;
          *nbOut+=pout;
          run16=(int16_t *)scratchPad;
          for(int i=0;i<pout;i++)
          {
            *outptr++=((float)run16[i])/32767.;
          }
         if(_channels>=5 )
            {
            CHANNEL_TYPE *p_ch_type = channelMapping;
        #define DOIT(x,y) if(_context->channel_layout & CH_##x) *(p_ch_type++)=CHTYP_##y;
                if(_context->codec_id == CODEC_ID_DTS)
                {
                    
                    DOIT(FRONT_LEFT,FRONT_LEFT);
                    DOIT(FRONT_RIGHT,FRONT_RIGHT);
                    DOIT(FRONT_CENTER,FRONT_CENTER);
                    DOIT(SIDE_LEFT,REAR_LEFT);
                    DOIT(SIDE_RIGHT,REAR_RIGHT);
                    DOIT(LOW_FREQUENCY,LFE);

                }else   
                {
                    DOIT(LOW_FREQUENCY,LFE);
                    DOIT(FRONT_LEFT,FRONT_LEFT);
                    DOIT(FRONT_CENTER,FRONT_CENTER);
                    DOIT(FRONT_RIGHT,FRONT_RIGHT);
                    DOIT(SIDE_LEFT,REAR_LEFT);
                    DOIT(SIDE_RIGHT,REAR_RIGHT);
                }
            }

        }
        
        
        
        return 1;
}
예제 #19
0
static BOOL tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const BYTE *data, UINT32 data_size, UINT32 extensions)
{
	TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
	int len;
	int frame_size;
	UINT32 src_size;
	const BYTE *src;
	BYTE *dst;
	int dst_offset;
#if 0
	WLog_DBG(TAG, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size));
	int i;
	for(i = 0; i < data_size; i++)
	{
		WLog_DBG(TAG, ("%02X ", data[i]));
		if (i % 16 == 15)
			WLog_DBG(TAG, ("\n"));
	}
#endif
	if (mdecoder->decoded_size_max == 0)
		mdecoder->decoded_size_max = MAX_AUDIO_FRAME_SIZE + 16;

	mdecoder->decoded_data = calloc(1, mdecoder->decoded_size_max);
	if (!mdecoder->decoded_data)
		return FALSE;

	/* align the memory for SSE2 needs */
	dst = (BYTE *)(((uintptr_t) mdecoder->decoded_data + 15) & ~ 0x0F);
	dst_offset = dst - mdecoder->decoded_data;
	src = data;
	src_size = data_size;
	while(src_size > 0)
	{
		/* Ensure enough space for decoding */
		if (mdecoder->decoded_size_max - mdecoder->decoded_size < MAX_AUDIO_FRAME_SIZE)
		{
			BYTE *tmp_data;

			tmp_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max * 2 + 16);
			if (!tmp_data)
				return FALSE;
			mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16;
			mdecoder->decoded_data = tmp_data;

			dst = (BYTE *)(((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
			if (dst - mdecoder->decoded_data != dst_offset)
			{
				/* re-align the memory if the alignment has changed after realloc */
				memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
				dst_offset = dst - mdecoder->decoded_data;
			}
			dst += mdecoder->decoded_size;
		}
		frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size;
#if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20)
		len = avcodec_decode_audio2(mdecoder->codec_context,
									(int16_t *) dst, &frame_size, src, src_size);
#else
		{
#if LIBAVCODEC_VERSION_MAJOR < 55
			AVFrame *decoded_frame = avcodec_alloc_frame();
#else
			AVFrame *decoded_frame = av_frame_alloc();
#endif
			int got_frame = 0;
			AVPacket pkt;
			av_init_packet(&pkt);
			pkt.data = (BYTE *) src;
			pkt.size = src_size;
			len = avcodec_decode_audio4(mdecoder->codec_context, decoded_frame, &got_frame, &pkt);
			if (len >= 0 && got_frame)
			{
				frame_size = av_samples_get_buffer_size(NULL, mdecoder->codec_context->channels,
														decoded_frame->nb_samples, mdecoder->codec_context->sample_fmt, 1);
				memcpy(dst, decoded_frame->data[0], frame_size);
			}
			av_free(decoded_frame);
		}
#endif
		if (len <= 0 || frame_size <= 0)
		{
			WLog_ERR(TAG, "error decoding");
			break;
		}
		src += len;
		src_size -= len;
		mdecoder->decoded_size += frame_size;
		dst += frame_size;
	}
	if (mdecoder->decoded_size == 0)
	{
		free(mdecoder->decoded_data);
		mdecoder->decoded_data = NULL;
	}
	else
		if (dst_offset)
		{
			/* move the aligned decoded data to original place */
			memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
		}
	DEBUG_TSMF("data_size %d decoded_size %d",
			   data_size, mdecoder->decoded_size);
	return TRUE;
}
예제 #20
0
int decode_audio_file(ChromaprintContext *chromaprint_ctx, int16_t *buffer1, int16_t *buffer2, const char *file_name, int max_length, int *duration)
{
	int i, ok = 0, remaining, length, consumed, buffer_size, codec_ctx_opened = 0;
	AVFormatContext *format_ctx = NULL;
	AVCodecContext *codec_ctx = NULL;
	AVCodec *codec = NULL;
	AVStream *stream = NULL;
	AVPacket packet, packet_temp;
#ifdef HAVE_AV_AUDIO_CONVERT
	AVAudioConvert *convert_ctx = NULL;
#endif
	int16_t *buffer;

	if (!strcmp(file_name, "-")) {
		file_name = "pipe:0";
	}

#if LIBAVFORMAT_VERSION_INT < AV_VERSION_INT(53, 2, 0)
	if (av_open_input_file(&format_ctx, file_name, NULL, 0, NULL) != 0) {
#else
	if (avformat_open_input(&format_ctx, file_name, NULL, NULL) != 0) {
#endif
		fprintf(stderr, "ERROR: couldn't open the file\n");
		goto done;
	}

	if (av_find_stream_info(format_ctx) < 0) {
		fprintf(stderr, "ERROR: couldn't find stream information in the file\n");
		goto done;
	}

	for (i = 0; i < format_ctx->nb_streams; i++) {
		codec_ctx = format_ctx->streams[i]->codec;
		if (codec_ctx && codec_ctx->codec_type == AVMEDIA_TYPE_AUDIO) {
			stream = format_ctx->streams[i];
			break;
		}
	}
	if (!stream) {
		fprintf(stderr, "ERROR: couldn't find any audio stream in the file\n");
		goto done;
	}

	codec = avcodec_find_decoder(codec_ctx->codec_id);
	if (!codec) {
		fprintf(stderr, "ERROR: unknown codec\n");
		goto done;
	}

	if (avcodec_open(codec_ctx, codec) < 0) {
		fprintf(stderr, "ERROR: couldn't open the codec\n");
		goto done;
	}
	codec_ctx_opened = 1;

	if (codec_ctx->channels <= 0) {
		fprintf(stderr, "ERROR: no channels found in the audio stream\n");
		goto done;
	}

	if (codec_ctx->sample_fmt != AV_SAMPLE_FMT_S16) {
#ifdef HAVE_AV_AUDIO_CONVERT
		convert_ctx = av_audio_convert_alloc(AV_SAMPLE_FMT_S16, codec_ctx->channels,
		                                     codec_ctx->sample_fmt, codec_ctx->channels, NULL, 0);
		if (!convert_ctx) {
			fprintf(stderr, "ERROR: couldn't create sample format converter\n");
			goto done;
		}
#else
		fprintf(stderr, "ERROR: unsupported sample format\n");
		goto done;
#endif
	}

	*duration = stream->time_base.num * stream->duration / stream->time_base.den;

	av_init_packet(&packet);
	av_init_packet(&packet_temp);

	remaining = max_length * codec_ctx->channels * codec_ctx->sample_rate;
	chromaprint_start(chromaprint_ctx, codec_ctx->sample_rate, codec_ctx->channels);

	while (1) {
		if (av_read_frame(format_ctx, &packet) < 0) {
			break;
		}

		packet_temp.data = packet.data;
		packet_temp.size = packet.size;

		while (packet_temp.size > 0) {
			buffer_size = BUFFER_SIZE;
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(52, 23, 0)
			consumed = avcodec_decode_audio2(codec_ctx,
				buffer1, &buffer_size, packet_temp.data, packet_temp.size);
#else
			consumed = avcodec_decode_audio3(codec_ctx,
				buffer1, &buffer_size, &packet_temp);
#endif

			if (consumed < 0) {
				break;
			}

			packet_temp.data += consumed;
			packet_temp.size -= consumed;

			if (buffer_size <= 0) {
				if (buffer_size < 0) {
					fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too small\n");
				}
				continue;
			}
			if (buffer_size > BUFFER_SIZE) {
				fprintf(stderr, "WARNING: size returned from avcodec_decode_audioX is too large\n");
				continue;
			}

#ifdef HAVE_AV_AUDIO_CONVERT
			if (convert_ctx) {
				const void *ibuf[6] = { buffer1 };
				void *obuf[6] = { buffer2 };
#if LIBAVUTIL_VERSION_INT < AV_VERSION_INT(51, 8, 0)
				int istride[6] = { av_get_bits_per_sample_format(codec_ctx->sample_fmt) / 8 };
#else
				int istride[6] = { av_get_bytes_per_sample(codec_ctx->sample_fmt) };
#endif
				int ostride[6] = { 2 };
				int len = buffer_size / istride[0];
				if (av_audio_convert(convert_ctx, obuf, ostride, ibuf, istride, len) < 0) {
					break;
				}
				buffer = buffer2;
				buffer_size = len * ostride[0];
			}
			else {
				buffer = buffer1;
			}
#else
			buffer = buffer1;
#endif

			length = MIN(remaining, buffer_size / 2);
			if (!chromaprint_feed(chromaprint_ctx, buffer, length)) {
				fprintf(stderr, "ERROR: fingerprint calculation failed\n");
				goto done;
			}

			if (max_length) {
				remaining -= length;
				if (remaining <= 0) {
					goto finish;
				}
			}
		}

		if (packet.data) {
			av_free_packet(&packet);
		}
	}

finish:
	if (!chromaprint_finish(chromaprint_ctx)) {
		fprintf(stderr, "ERROR: fingerprint calculation failed\n");
		goto done;
	}

	ok = 1;

done:
	if (codec_ctx_opened) {
		avcodec_close(codec_ctx);
	}
	if (format_ctx) {
		av_close_input_file(format_ctx);
	}
#ifdef HAVE_AV_AUDIO_CONVERT
	if (convert_ctx) {
		av_audio_convert_free(convert_ctx);
	}
#endif
	return ok;
}

int fpcalc_main(int argc, char **argv)
{
	int i, j, max_length = 120, num_file_names = 0, raw = 0, raw_fingerprint_size, duration;
	int16_t *buffer1, *buffer2;
	int32_t *raw_fingerprint;
	char *file_name, *fingerprint, **file_names;
	ChromaprintContext *chromaprint_ctx;
	int algo = CHROMAPRINT_ALGORITHM_DEFAULT;

	file_names = malloc(argc * sizeof(char *));
	for (i = 1; i < argc; i++) {
		char *arg = argv[i];
		if (!strcmp(arg, "-length") && i + 1 < argc) {
			max_length = atoi(argv[++i]);
		}
		else if (!strcmp(arg, "-version") || !strcmp(arg, "-v")) {
			printf("fpcalc version %s\n", chromaprint_get_version());
			return 0;
		}
		else if (!strcmp(arg, "-raw")) {
			raw = 1;
		}
		else if (!strcmp(arg, "-algo") && i + 1 < argc) {
			const char *v = argv[++i];
			if (!strcmp(v, "test1")) { algo = CHROMAPRINT_ALGORITHM_TEST1; }
			else if (!strcmp(v, "test2")) { algo = CHROMAPRINT_ALGORITHM_TEST2; }
			else if (!strcmp(v, "test3")) { algo = CHROMAPRINT_ALGORITHM_TEST3; }
			else if (!strcmp(v, "test4")) { algo = CHROMAPRINT_ALGORITHM_TEST4; }
			else {
				fprintf(stderr, "WARNING: unknown algorithm, using the default\n");
			}
		}
		else if (!strcmp(arg, "-set") && i + 1 < argc) {
			i += 1;
		}
		else {
			file_names[num_file_names++] = argv[i];
		}
	}

	if (!num_file_names) {
		printf("usage: %s [OPTIONS] FILE...\n\n", argv[0]);
		printf("Options:\n");
		printf("  -version      print version information\n");
		printf("  -length SECS  length of the audio data used for fingerprint calculation (default 120)\n");
		printf("  -raw          output the raw uncompressed fingerprint\n");
		printf("  -algo NAME    version of the fingerprint algorithm\n");
		return 2;
	}

	av_register_all();
	av_log_set_level(AV_LOG_ERROR);

	buffer1 = av_malloc(BUFFER_SIZE + 16);
	buffer2 = av_malloc(BUFFER_SIZE + 16);
	chromaprint_ctx = chromaprint_new(algo);

	for (i = 1; i < argc; i++) {
		char *arg = argv[i];
		if (!strcmp(arg, "-set") && i + 1 < argc) {
			char *name = argv[++i];
			char *value = strchr(name, '=');
			if (value) {
				*value++ = '\0';
				chromaprint_set_option(chromaprint_ctx, name, atoi(value));
			}
		}
	}

	for (i = 0; i < num_file_names; i++) {
		file_name = file_names[i];
		if (!decode_audio_file(chromaprint_ctx, buffer1, buffer2, file_name, max_length, &duration)) {
			fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
			continue;
		}
		if (i > 0) {
			printf("\n");
		}
		printf("FILE=%s\n", file_name);
		printf("DURATION=%d\n", duration);
		if (raw) {
			if (!chromaprint_get_raw_fingerprint(chromaprint_ctx, (void **)&raw_fingerprint, &raw_fingerprint_size)) {
				fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
				continue;
			}
			printf("FINGERPRINT=");
			for (j = 0; j < raw_fingerprint_size; j++) {
				printf("%d%s", raw_fingerprint[j], j + 1 < raw_fingerprint_size ? "," : "");
			}
			printf("\n");
			chromaprint_dealloc(raw_fingerprint);
		}
		else {
			if (!chromaprint_get_fingerprint(chromaprint_ctx, &fingerprint)) {
				fprintf(stderr, "ERROR: unable to calculate fingerprint for file %s, skipping\n", file_name);
				continue;
			}
			printf("FINGERPRINT=%s\n", fingerprint);
			chromaprint_dealloc(fingerprint);
		}
	}

	chromaprint_free(chromaprint_ctx);
	av_free(buffer1);
	av_free(buffer2);
	free(file_names);

	return 0;
}
예제 #21
0
int Libav::decodeNextAudio(void) throw (AVException*)
{
	
	int bytes;
	int numSamples;
	
	// int bytesPerSample = (this->getSampleSize() * this->getSampleChannels());
	
	
	//NSLog(@"> [libav decodeNextAudio] sample counter: %d",sampleCounter);
	// there must be another way to initialise the audio decoder than this sampleCounter test.
	
	if (!this->isOpen)
		this->open();
	
	if (sampleCounter == 0)
	{
		//pFrame=avcodec_alloc_frame();
		pFrame=av_frame_alloc();
		if (!pFrame)
			throw new AVException ("Unable to allocate AUDIO buffer",MEMORY_ALLOCATION_ERROR);
		//avcodec_get_frame_defaults(pFrame);		
		av_frame_unref(pFrame);
	}
	
	// we don't know SPS until we decode the first frame. 
	// we cannot calculate SamplesOut without SPS.
	// what can we do here.  Assume that once the sampleCounter is above 0 the SPS will be set.
	
	//	NSLog (@"sampleCounter: %d  samplesOut: %d", sampleCounter, [self getSamplesOut]);
	
	if (sampleCounter > 0) 
		if (this->compareSamplesRange(sampleCounter) > 0)
			return -1;
	
	// loop until we are passed the frame in marker
	do {
		//	NSLog(@"[libav decodeNextAudio] before IN loop");
		
#if LIBAVFORMAT_VERSION_MAJOR  < 54
		;
#else
		AVFrame *iFrame;
#endif
		int gotFrame = 1;
		
		// loop until "gotFrame"
		do {
			//  NSLog(@"[libav decodeNextAudio] gotFrame");
			
			// Find our specified stream
			do {
				// NSLog(@"[libav decodeNextAudio] != avStream: %d",avStream);
				
				bytes = av_read_frame(pFormatCtx, &packet);
				if (bytes < 0) 
					return bytes;
			} while (packet.stream_index != avStream) ;
			
			// int len;
			
#if LIBAVFORMAT_VERSION_MAJOR  < 50
			avcodec_decode_audio2(pCodecCtx, aBuffer, &numBytes, packet.data, packet.size);
#elseif LIBAVFORMAT_VERSION_MAJOR  < 54
			avcodec_decode_audio3(pCodecCtx, aBuffer, &numBytes, &packet);
#else				
			gotFrame = 0;
			//iFrame=avcodec_alloc_frame();
			iFrame=av_frame_alloc();
			//avcodec_get_frame_defaults(iFrame);
			av_frame_unref(iFrame);
			
			avcodec_decode_audio4(pCodecCtx, iFrame, &gotFrame, &packet);
			//			NSLog (@"avcodec_decode_audio4 len: %d gotFrame: %d",len,gotFrame);
			
			if (gotFrame) {
				/* if a frame has been decoded, output it */
				bytes = av_samples_get_buffer_size(NULL, pCodecCtx->channels,
												   iFrame->nb_samples,
												   pCodecCtx->sample_fmt, 1);
				
				//		NSLog (@"decode Audio sps: %d",iFrame->sample_rate);
				//		NSLog (@"audio samples decoded: %d",iFrame->nb_samples);
				if (sampleCounter == 0)
					this->setSamplesPerSecond(iFrame->sample_rate);
			}
			
#endif
			//NSLog(@"decoded: %d finished: %d",len,gotFrame);
			
		} while (!gotFrame);
		
		
		int bytesPerSample = (this->getSampleSize() * this->getSampleChannels());			
		numSamples = bytes / bytesPerSample;
		int64_t endCounter = sampleCounter + numSamples;
		pFrame->nb_samples =numSamples;
		//	NSLog(@"bytesPerSample: %d, numSamples: %d",bytesPerSample,numSamples);
		if (this->compareSamplesRange(endCounter) >=0) {
			if ((this->compareSamplesRange(sampleCounter)<0) && (this->compareSamplesRange(endCounter) >0))
			{
				// send partial frame
				//NSLog(@"partial case 1");
				
                if ((this->getSamplesOut() - this->getSamplesIn()) > INT_MAX) {
                    throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR);
                }
                
				pFrame->nb_samples =(this->getSamplesOut() - this->getSamplesIn()) ;
				avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(),
										 iFrame->data[0] + (this->getSamplesIn() - sampleCounter) * bytesPerSample,
										 pFrame->nb_samples* bytesPerSample , 1);
			}
			else if ((this->compareSamplesRange(sampleCounter)<0) && (this->compareSamplesRange(endCounter) ==0))
			{
				// send partial frame
				//NSLog(@"partial case 2");
				
                if ((sampleCounter + numSamples - this->getSamplesIn() + 1) > INT_MAX) {
                    throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR);
                }

                
				pFrame->nb_samples =( sampleCounter + numSamples - this->getSamplesIn() + 1) ;
				avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(),
										 iFrame->data[0] + (this->getSamplesIn() - sampleCounter) * bytesPerSample,
										 pFrame->nb_samples* bytesPerSample,1);
				
			} 
			else if ((this->compareSamplesRange(sampleCounter)==0) && (this->compareSamplesRange(endCounter) >0))
			{
				// send partial frame
				//NSLog(@"partial case 3");
				
                if ((this->getSamplesOut() - sampleCounter) > INT_MAX) {
                    throw new AVException(std::string("Sample Range Too Large"),SAMPLE_RANGE_ERROR);
                }

                
				pFrame->nb_samples =( this->getSamplesOut() - sampleCounter);
				avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(),
										 iFrame->data[0],
										 pFrame->nb_samples * bytesPerSample,1);
				
			}
			else 
			{
				// send entire frame.
				//NSLog(@"full case: %d",numSamples);
				
				//	NSLog(@"pic buffer: %x pframe->data[0]: %x",pictureBuffer,pFrame->data[0]);
				
				pFrame->nb_samples =numSamples;
				
				avcodec_fill_audio_frame(pFrame, this->getSampleChannels(), this->getSampleFormat(),
										 iFrame->data[0],bytes,1);
				//			memset(pFrame->data[0],127,bytes);
			}
		}
		
		//avcodec_free_frame(&iFrame);
		av_frame_free(&iFrame);
		av_free(iFrame);
#if LIBAVFORMAT_VERSION_MAJOR  < 57	
		av_free_packet(&packet);
#else
		av_packet_unref(&packet);
#endif
		
		
		sampleCounter += pFrame->nb_samples;
		
		//	NSLog(@"sample counter: %d",sampleCounter);
		
	} while (this->compareSamplesRange(sampleCounter) < 0);			
	//	NSLog(@"< [libav decodeNextAudio] %d %d ",pFrame->nb_samples , bytes) ;
	
	return pFrame->nb_samples;
}
예제 #22
0
static gint
player_av_get_audio_frame (PlayerAV *self, short *dest, int64_t *pts)
{
    static AVPacket *packet = NULL;
    static uint8_t *pkt_data = NULL;
    static int pkt_size = 0;

    int len1, data_size;

    for (;;) {
        while (pkt_size > 0) {
            data_size = AVCODEC_MAX_AUDIO_FRAME_SIZE * self->priv->actx->channels;

            len1 = avcodec_decode_audio2 (self->priv->actx, dest,
                &data_size, pkt_data, pkt_size);

            if (len1 < 0) {
                pkt_size = 0;
                break;
            }

            *pts = packet->pts;

            pkt_data += len1;
            pkt_size -= len1;

            if (data_size <= 0)
                continue;

            return data_size;
        }

        for (;;) {
            // Free old packet
            if (packet) {
                if (packet->data != NULL)
                    av_free_packet (packet);
                av_free (packet);
                packet = NULL;
            }

            if (g_async_queue_length (self->priv->apq) > 0) {
                packet = (AVPacket*) g_async_queue_pop (self->priv->apq);
                break;
            } else {
                packet = (AVPacket*) av_mallocz (sizeof (AVPacket));
                // Read new packet

                g_mutex_lock (self->priv->rp_mutex);

                if(av_read_frame (self->priv->fctx, packet) < 0) {
                    g_mutex_unlock (self->priv->rp_mutex);
                    return -1;
                }

                if (packet->stream_index == self->priv->astream) {
                    g_mutex_unlock (self->priv->rp_mutex);
                    break;
                } else if (packet->stream_index == self->priv->vstream) {
                    g_async_queue_push (self->priv->vpq, packet);
                    packet = NULL;
                }

                g_mutex_unlock (self->priv->rp_mutex);
            }
        }

        pkt_data = packet->data;
        pkt_size = packet->size;
    }
}
예제 #23
0
파일: audio.c 프로젝트: shanewfx/vlc-arib
/*****************************************************************************
 * DecodeAudio: Called to decode one frame
 *****************************************************************************/
aout_buffer_t * DecodeAudio ( decoder_t *p_dec, block_t **pp_block )
{
    decoder_sys_t *p_sys = p_dec->p_sys;
    int i_used, i_output;
    aout_buffer_t *p_buffer;
    block_t *p_block;

    if( !pp_block || !*pp_block ) return NULL;

    p_block = *pp_block;

    if( p_block->i_flags & (BLOCK_FLAG_DISCONTINUITY|BLOCK_FLAG_CORRUPTED) )
    {
        block_Release( p_block );
        avcodec_flush_buffers( p_sys->p_context );
        p_sys->i_samples = 0;
        date_Set( &p_sys->end_date, 0 );

        if( p_sys->i_codec_id == CODEC_ID_MP2 || p_sys->i_codec_id == CODEC_ID_MP3 )
            p_sys->i_reject_count = 3;
        return NULL;
    }

    if( p_sys->i_samples > 0 )
    {
        /* More data */
        p_buffer = SplitBuffer( p_dec );
        if( !p_buffer ) block_Release( p_block );
        return p_buffer;
    }

    if( !date_Get( &p_sys->end_date ) && !p_block->i_pts )
    {
        /* We've just started the stream, wait for the first PTS. */
        block_Release( p_block );
        return NULL;
    }

    if( p_block->i_buffer <= 0 )
    {
        block_Release( p_block );
        return NULL;
    }

    if( (p_block->i_flags & BLOCK_FLAG_PRIVATE_REALLOCATED) == 0 )
    {
        *pp_block = p_block = block_Realloc( p_block, 0, p_block->i_buffer + FF_INPUT_BUFFER_PADDING_SIZE );
        if( !p_block )
            return NULL;
        p_block->i_buffer -= FF_INPUT_BUFFER_PADDING_SIZE;
        memset( &p_block->p_buffer[p_block->i_buffer], 0, FF_INPUT_BUFFER_PADDING_SIZE );

        p_block->i_flags |= BLOCK_FLAG_PRIVATE_REALLOCATED;
    }

    do
    {
        i_output = __MAX( p_block->i_buffer, p_sys->i_output_max );
        if( i_output > p_sys->i_output_max )
        {
            /* Grow output buffer if necessary (eg. for PCM data) */
            p_sys->p_output = av_realloc( p_sys->p_output, i_output );
        }

#if LIBAVCODEC_VERSION_INT >= AV_VERSION_INT( 52, 0, 0 )
        i_used = avcodec_decode_audio2( p_sys->p_context,
                                       (int16_t*)p_sys->p_output, &i_output,
                                       p_block->p_buffer, p_block->i_buffer );
#else
        i_used = avcodec_decode_audio( p_sys->p_context,
                                       (int16_t*)p_sys->p_output, &i_output,
                                       p_block->p_buffer, p_block->i_buffer );
#endif

        if( i_used < 0 || i_output < 0 )
        {
            if( i_used < 0 )
                msg_Warn( p_dec, "cannot decode one frame (%zu bytes)",
                          p_block->i_buffer );

            block_Release( p_block );
            return NULL;
        }
        else if( (size_t)i_used > p_block->i_buffer )
        {
            i_used = p_block->i_buffer;
        }

        p_block->i_buffer -= i_used;
        p_block->p_buffer += i_used;

    } while( p_block->i_buffer > 0 && i_output <= 0 );

    if( p_sys->p_context->channels <= 0 || p_sys->p_context->channels > 8 ||
        p_sys->p_context->sample_rate <= 0 )
    {
        msg_Warn( p_dec, "invalid audio properties channels count %d, sample rate %d",
                  p_sys->p_context->channels, p_sys->p_context->sample_rate );
        block_Release( p_block );
        return NULL;
    }

    if( p_dec->fmt_out.audio.i_rate != (unsigned int)p_sys->p_context->sample_rate )
    {
        date_Init( &p_sys->end_date, p_sys->p_context->sample_rate, 1 );
        date_Set( &p_sys->end_date, p_block->i_pts );
    }

    /* **** Set audio output parameters **** */
    SetupOutputFormat( p_dec, true );

    if( p_block->i_pts != 0 &&
        p_block->i_pts != date_Get( &p_sys->end_date ) )
    {
        date_Set( &p_sys->end_date, p_block->i_pts );
    }
    p_block->i_pts = 0;

    /* **** Now we can output these samples **** */
    p_sys->i_samples = i_output / (p_dec->fmt_out.audio.i_bitspersample / 8) / p_sys->p_context->channels;
    p_sys->p_samples = p_sys->p_output;

    /* Silent unwanted samples */
    if( p_sys->i_reject_count > 0 )
    {
        memset( p_sys->p_output, 0, i_output );
        p_sys->i_reject_count--;
    }

    p_buffer = SplitBuffer( p_dec );
    if( !p_buffer ) block_Release( p_block );
    return p_buffer;
}
/** buffer management callback function for AMR decoding in new standard
 * of FFmpeg library
 */
void omx_amr_audiodec_component_BufferMgmtCallback(OMX_COMPONENTTYPE *openmaxStandComp, OMX_BUFFERHEADERTYPE* pInputBuffer, OMX_BUFFERHEADERTYPE* pOutputBuffer)
{
    omx_amr_audiodec_component_PrivateType* omx_amr_audiodec_component_Private = openmaxStandComp->pComponentPrivate;
    int output_length, len;
    OMX_ERRORTYPE err;

    DEBUG(DEB_LEV_FUNCTION_NAME, "In %s\n",__func__);

    if(omx_amr_audiodec_component_Private->isFirstBuffer == OMX_TRUE) {
        omx_amr_audiodec_component_Private->isFirstBuffer = OMX_FALSE;

        if((pInputBuffer->nFlags & OMX_BUFFERFLAG_CODECCONFIG) == OMX_BUFFERFLAG_CODECCONFIG) {
            omx_amr_audiodec_component_Private->extradata_size = pInputBuffer->nFilledLen;
            if(omx_amr_audiodec_component_Private->extradata_size > 0) {
                if(omx_amr_audiodec_component_Private->extradata) {
                    free(omx_amr_audiodec_component_Private->extradata);
                }
                omx_amr_audiodec_component_Private->extradata = malloc(pInputBuffer->nFilledLen);
                memcpy(omx_amr_audiodec_component_Private->extradata, pInputBuffer->pBuffer,pInputBuffer->nFilledLen);
            }

            DEBUG(DEB_ALL_MESS, "In %s Received First Buffer Extra Data Size=%d\n",__func__,(int)pInputBuffer->nFilledLen);
            pInputBuffer->nFlags = 0x0;
            pInputBuffer->nFilledLen = 0;
        }

        if (!omx_amr_audiodec_component_Private->avcodecReady) {
            err = omx_amr_audiodec_component_ffmpegLibInit(omx_amr_audiodec_component_Private);
            if (err != OMX_ErrorNone) {
                DEBUG(DEB_LEV_ERR, "In %s omx_amr_audiodec_component_ffmpegLibInit Failed\n",__func__);
                return;
            }
            omx_amr_audiodec_component_Private->avcodecReady = OMX_TRUE;
        }

        if(pInputBuffer->nFilledLen == 0) {
            return;
        }
    }

    if(omx_amr_audiodec_component_Private->avcodecReady == OMX_FALSE) {
        DEBUG(DEB_LEV_ERR, "In %s avcodec Not Ready \n",__func__);
        return;
    }

    if(omx_amr_audiodec_component_Private->isNewBuffer) {
        omx_amr_audiodec_component_Private->isNewBuffer = 0;
    }
    pOutputBuffer->nFilledLen = 0;
    pOutputBuffer->nOffset=0;
    /** resetting output length to a predefined value */
    output_length = OUTPUT_LEN_STANDARD_FFMPEG;
#if FFMPEG_DECODER_VERSION >= 2
    len  = avcodec_decode_audio2(omx_amr_audiodec_component_Private->avCodecContext,
                                 (short*)(pOutputBuffer->pBuffer),
                                 &output_length,
                                 pInputBuffer->pBuffer,
                                 pInputBuffer->nFilledLen);
#else
    len  = avcodec_decode_audio(omx_amr_audiodec_component_Private->avCodecContext,
                                (short*)(pOutputBuffer->pBuffer),
                                &output_length,
                                pInputBuffer->pBuffer,
                                pInputBuffer->nFilledLen);
#endif
    if((omx_amr_audiodec_component_Private->pAudioPcmMode.nSamplingRate != omx_amr_audiodec_component_Private->avCodecContext->sample_rate) ||
            ( omx_amr_audiodec_component_Private->pAudioPcmMode.nChannels!=omx_amr_audiodec_component_Private->avCodecContext->channels)) {
        DEBUG(DEB_LEV_FULL_SEQ, "---->Sending Port Settings Change Event\n");
        //switch for different audio formats---parameter settings accordingly
        switch(omx_amr_audiodec_component_Private->audio_coding_type)  {
        /*Update Parameter which has changed from avCodecContext*/
        case OMX_AUDIO_CodingAMR :
            /*pAudioAMR is for input port AMR data*/
            omx_amr_audiodec_component_Private->pAudioAmr.nChannels   = omx_amr_audiodec_component_Private->avCodecContext->channels;
            omx_amr_audiodec_component_Private->pAudioAmr.nBitRate    = omx_amr_audiodec_component_Private->avCodecContext->bit_rate;
            break;
        default :
            DEBUG(DEB_LEV_ERR, "Audio format other than AMR not supported\nCodec type %lu not found\n",omx_amr_audiodec_component_Private->audio_coding_type);
            break;
        }//end of switch

        /*pAudioPcmMode is for output port PCM data*/
        omx_amr_audiodec_component_Private->pAudioPcmMode.nChannels = omx_amr_audiodec_component_Private->avCodecContext->channels;
        if(omx_amr_audiodec_component_Private->avCodecContext->sample_fmt==SAMPLE_FMT_S16)
            omx_amr_audiodec_component_Private->pAudioPcmMode.nBitPerSample = 16;
        else if(omx_amr_audiodec_component_Private->avCodecContext->sample_fmt==SAMPLE_FMT_S32)
            omx_amr_audiodec_component_Private->pAudioPcmMode.nBitPerSample = 32;
        omx_amr_audiodec_component_Private->pAudioPcmMode.nSamplingRate = omx_amr_audiodec_component_Private->avCodecContext->sample_rate;

        /*Send Port Settings changed call back*/
        (*(omx_amr_audiodec_component_Private->callbacks->EventHandler))
        (openmaxStandComp,
         omx_amr_audiodec_component_Private->callbackData,
         OMX_EventPortSettingsChanged, /* The command was completed */
         0,
         1, /* This is the output port index */
         NULL);
    }

    if(len < 0) {
        DEBUG(DEB_LEV_ERR,"error in packet decoding in audio dcoder \n");
    } else {
        /*If output is max length it might be an error, so Don't send output buffer*/
        if((output_length != OUTPUT_LEN_STANDARD_FFMPEG) || (output_length <= pOutputBuffer->nAllocLen)) {
            pOutputBuffer->nFilledLen += output_length;
        }
        pInputBuffer->nFilledLen = 0;
        omx_amr_audiodec_component_Private->isNewBuffer = 1;
    }

    /** return output buffer */
}
		ByteArray DefaultReader::readFrame( double & duration, bool & stop ) {
			stop = false;
			// static just for speed
			static uint8_t audio_buf[AVCODEC_MAX_AUDIO_FRAME_SIZE*3/2];
			int ret = 0;

			int dp_len, data_size;

			ByteArray data;

			ret = av_read_frame( this->pFormatContext_.get(), this->pPacket_.get() );
			if( ret < 0 ) {
				stop = true;
				return data;
			}
			int64_t curPts = -1;
			int64_t decoded = 0;
			if( this->pPacket_->pts != static_cast< int64_t >( AV_NOPTS_VALUE ) ) {
				curPts = av_rescale(
					this->pPacket_->pts,
					AV_TIME_BASE * static_cast< int64_t >( this->pStream_->time_base.num ),
					this->pStream_->time_base.den
				);
			}
#if LIBAVCODEC_VERSION_MAJOR < 53
			uint8_t * audio_pkt_data = this->pPacket_->data;
			int audio_pkt_size = this->pPacket_->size;
			while( audio_pkt_size > 0 ) {
#else
			uint8_t * pktDataBackup = this->pPacket_->data;
			while( this->pPacket_->size > 0 ) {
#endif
				if( this->afterEnd( toGeneral( curPts ) ) ) {
					stop = true;
					break;
				}
				data_size = sizeof( audio_buf );
#if LIBAVCODEC_VERSION_MAJOR < 53
				dp_len = avcodec_decode_audio2(
					this->pCodecContext_.get(),
					static_cast< int16_t * >( static_cast< void * >( audio_buf ) ),
					&data_size,
					audio_pkt_data,
					audio_pkt_size
				);
#else
				dp_len = avcodec_decode_audio3(
					this->pCodecContext_.get(),
					static_cast< int16_t * >( static_cast< void * >( audio_buf ) ),
					&data_size,
					this->pPacket_.get()
				);
#endif
				if( dp_len < 0 ) {
#if LIBAVCODEC_VERSION_MAJOR < 53
					audio_pkt_size = 0;
#endif
					break;
				}
#if LIBAVCODEC_VERSION_MAJOR < 53
				audio_pkt_data += dp_len;
				audio_pkt_size -= dp_len;
#else
				this->pPacket_->data += dp_len;
				this->pPacket_->size -= dp_len;
#endif
				if( data_size <= 0 ) {
					continue;
				}
				int64_t ptsDiff = (static_cast< int64_t >( AV_TIME_BASE )/2 * data_size) / (this->pCodecContext_->sample_rate * this->pCodecContext_->channels);
				if( this->afterBegin( toGeneral( curPts ) ) ) {
					data.insert( data.end(), audio_buf, audio_buf + data_size );
					decoded += ptsDiff;
				}
				curPts += ptsDiff;
			}
#if LIBAVCODEC_VERSION_MAJOR < 53
			if( this->pPacket_->data ) {
#else
			if( pktDataBackup ) {
				this->pPacket_->data = pktDataBackup;
#endif
				av_free_packet( this->pPacket_.get() );
			}

			duration = static_cast< double >( decoded ) / AV_TIME_BASE;

			return data;
		}

		bool DefaultReader::seekFrame( double timestamp ) {
			timestamp = av_rescale( timestamp, pStream_->time_base.den, pStream_->time_base.num );
			int succeed = av_seek_frame( this->pFormatContext_.get(), pStream_->index, timestamp, AVSEEK_FLAG_ANY | AVSEEK_FLAG_BACKWARD );
			if( succeed >= 0 ) {
				avcodec_flush_buffers( this->pCodecContext_.get() );
			}
			return succeed >= 0;
		}

	}
예제 #26
0
static size_t ffmpeg_read_one_packet(struct input_handle* ih) {
  for (;;) {
    if (ih->need_new_frame && av_read_frame(ih->format_context, &ih->packet) < 0) {
      return 0;
    }

    ih->need_new_frame = FALSE;
    if (ih->packet.stream_index == ih->audio_stream) {
      int16_t* data_short =  (int16_t*) &ih->audio_buf;
      int32_t* data_int =    (int32_t*) &ih->audio_buf;
      float*   data_float =  (float*)   &ih->audio_buf;
      double*  data_double = (double*)  &ih->audio_buf;

      if (!ih->old_data) {
        ih->old_data = ih->packet.data;
      }
      while (ih->packet.size > 0) {
        int data_size = sizeof(ih->audio_buf);
#if LIBAVCODEC_VERSION_MAJOR >= 53 || \
    (LIBAVCODEC_VERSION_MAJOR == 52 && \
     LIBAVCODEC_VERSION_INT >= AV_VERSION_INT(52, 23, 0))
        int len = avcodec_decode_audio3(ih->codec_context, (int16_t*) &ih->audio_buf,
                                        &data_size, &ih->packet);
#else
        int len = avcodec_decode_audio2(ih->codec_context, (int16_t*) &ih->audio_buf,
                                        &data_size, ih->packet.data, ih->packet.size);
#endif
        if (len < 0) {
          ih->packet.size = 0;
          break;
        }
        ih->packet.data += len;
        ih->packet.size -= len;
        if (!data_size) {
          continue;
        }
        if (ih->packet.size < 0) {
            fprintf(stderr, "Error in decoder!\n");
            return 0;
        }
        size_t nr_frames_read, i;
        switch (ih->codec_context->sample_fmt) {
          case AV_SAMPLE_FMT_U8:
            fprintf(stderr, "8 bit audio not supported by libebur128!\n");
            return 0;
          case AV_SAMPLE_FMT_S16:
            nr_frames_read = (size_t) data_size / sizeof(int16_t) /
                             (size_t) ih->codec_context->channels;
            for (i = 0; i < (size_t) data_size / sizeof(int16_t); ++i) {
              ih->buffer[i] = ((float) data_short[i]) /
                              MAX(-(float) SHRT_MIN, (float) SHRT_MAX);
            }
            break;
          case AV_SAMPLE_FMT_S32:
            nr_frames_read = (size_t) data_size / sizeof(int32_t) /
                             (size_t) ih->codec_context->channels;
            for (i = 0; i < (size_t) data_size / sizeof(int32_t); ++i) {
              ih->buffer[i] = ((float) data_int[i]) /
                              MAX(-(float) INT_MIN, (float) INT_MAX);
            }
            break;
          case AV_SAMPLE_FMT_FLT:
            nr_frames_read = (size_t) data_size / sizeof(float) /
                             (size_t) ih->codec_context->channels;
            for (i = 0; i < (size_t) data_size / sizeof(float); ++i) {
              ih->buffer[i] = data_float[i];
            }
            break;
          case AV_SAMPLE_FMT_DBL:
            nr_frames_read = (size_t) data_size / sizeof(double) /
                             (size_t) ih->codec_context->channels;
            for (i = 0; i < (size_t) data_size / sizeof(double); ++i) {
              ih->buffer[i] = (float) data_double[i];
            }
            break;
          case AV_SAMPLE_FMT_NONE:
          case AV_SAMPLE_FMT_NB:
          default:
            fprintf(stderr, "Unknown sample format!\n");
            return 0;
        }
        return nr_frames_read;
      }
      ih->packet.data = ih->old_data;
      ih->old_data = NULL;
    }
    av_free_packet(&ih->packet);
    ih->need_new_frame = TRUE;
  }
}
예제 #27
0
파일: vineo.c 프로젝트: abitvin/vineo
static int nextDataAudio( Vineo *v, void *data, int length )
{
    int dec = 0;

    while( dec < length )
    {
        // If there's any pending decoded data, deal with it first
        if( v->dec_data_size > 0 )
        {
            // Get the amount of bytes remaining to be written, and clamp to
            // the amount of decoded data we have
            size_t rem = length - dec;

            if( rem > v->dec_data_size ) {
                rem = v->dec_data_size;
            }

            // Copy the data to the app's buffer and increment
            memcpy( data, v->dec_data, rem );
            data = (char*)data + rem;
            dec += rem;

            // If there's any decoded data left, move it to the front of the
            // buffer for next time
            if( rem < v->dec_data_size ) {
                memmove( v->dec_data, &v->dec_data[rem], v->dec_data_size - rem );
            }

            v->dec_data_size -= rem;
        }

        // Check if we need to get more decoded data
        if( v->dec_data_size == 0 )
        {
            size_t insize = v->data_size;
            int size, len;

            if( insize == 0 )
            {
                nextPacketAudio( v );

                // If there's no more input data, break and return what we have
                if( v->data_size == 0 ) {
                    break;
                }

                insize = v->data_size;
                memset( &v->data[insize], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }

            // Clear the input padding bits
            // Decode some data, and check for errors
            size = AVCODEC_MAX_AUDIO_FRAME_SIZE;

            while( ( len = avcodec_decode_audio2( v->aud_codec_ctx, (int16_t*)v->dec_data, &size, (unsigned char*)v->data, insize ) ) == 0 )
            {
                if( size > 0 ) {
                    break;
                }

                nextPacketAudio( v );

                if( insize == v->data_size ) {
                    break;
                }

                insize = v->data_size;
                memset( &v->data[insize], 0, FF_INPUT_BUFFER_PADDING_SIZE );
            }

            // we got an error! return what we got.
            if( len < 0 ) {
                break;
            }

            if( len > 0 )
            {
                // If any input data is left, move it to the start of the
                // buffer, and decrease the buffer size

                size_t rem = insize - len;

                if( rem ) {
                    memmove( v->data, &v->data[len], rem );
                }

                v->data_size = rem;
            }

            // Set the output buffer size
            v->dec_data_size = size;
        }
    }

    // Return the number of bytes we were able to get
    return dec;
}
예제 #28
0
int AudioLoader::decode_audio_frame(AVCodecContext* audioCtx,
                                    int16_t* output,
                                    int* outputSize,
                                    AVPacket* packet) {


#if LIBAVCODEC_VERSION_INT < AVCODEC_51_28_0

    int len = avcodec_decode_audio(audioCtx, output, outputSize,
                                 packet->data, packet->size);

#elif LIBAVCODEC_VERSION_INT < AVCODEC_52_47_0

    int len = avcodec_decode_audio2(audioCtx, output, outputSize,
                                    packet->data, packet->size);

#elif LIBAVCODEC_VERSION_INT < AVCODEC_AUDIO_DECODE4

    int len = avcodec_decode_audio3(audioCtx, output, outputSize,
                                    packet);

#else

    int gotFrame = 0;
    avcodec_get_frame_defaults(_decodedFrame);

    int len = avcodec_decode_audio4(audioCtx, _decodedFrame, &gotFrame, packet);

    if (len < 0) return len; // error handling should be done outside

    if (gotFrame) {
        int nsamples = _decodedFrame->nb_samples;
        int inputDataSize = av_samples_get_buffer_size(NULL, audioCtx->channels, nsamples,
                                                       audioCtx->sample_fmt, 1);

#  if HAVE_SWRESAMPLE
        if (_convertCtx) {
            int outputSamples = *outputSize / (2 /*sizeof(S16)*/ * _nChannels);
            //if (outputSamples < nsamples) { cout << "OOPS!!" << endl; }

            if (swr_convert(_convertCtx,
                            (uint8_t**) &output, outputSamples,
                            (const uint8_t**)_decodedFrame->data, nsamples) < 0) {
                ostringstream msg;
                msg << "AudioLoader: Error converting"
                    << " from " << av_get_sample_fmt_name(_audioCtx->sample_fmt)
                    << " to "   << av_get_sample_fmt_name(AV_SAMPLE_FMT_S16);
                throw EssentiaException(msg);
            }
            *outputSize = nsamples * (2 /*sizeof(S16)*/ * _nChannels);
        }
        else {
            // no conversion needed, make a direct copy
            // copy and convert data from our frame to our output audio buffer
            //E_WARNING("Should use swresample always!");
            memcpy(output, _decodedFrame->data[0], inputDataSize);
            *outputSize = inputDataSize;
        }
#  else
        // direct copy, we do the sample format conversion later if needed
        memcpy(output, _decodedFrame->data[0], inputDataSize);
        *outputSize = inputDataSize;
#  endif

    }
    else {
        E_DEBUG(EAlgorithm, "AudioLoader: tried to decode packet but didn't get any frame...");
        *outputSize = 0;
    }

#endif

    return len;
}
예제 #29
0
static boolean tsmf_ffmpeg_decode_audio(ITSMFDecoder* decoder, const uint8* data, uint32 data_size, uint32 extensions)
{
	TSMFFFmpegDecoder* mdecoder = (TSMFFFmpegDecoder*) decoder;
	int len;
	int frame_size;
	uint32 src_size;
	const uint8* src;
	uint8* dst;
	int dst_offset;

#if 0
	LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size));
	int i;
	for (i = 0; i < data_size; i++)
	{
		LLOG(0, ("%02X ", data[i]));
		if (i % 16 == 15)
			LLOG(0, ("\n"));
	}
	LLOG(0, ("\n"));
#endif

	if (mdecoder->decoded_size_max == 0)
		mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE + 16;
	mdecoder->decoded_data = xzalloc(mdecoder->decoded_size_max);
	/* align the memory for SSE2 needs */
	dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
	dst_offset = dst - mdecoder->decoded_data;
	src = data;
	src_size = data_size;

	while (src_size > 0)
	{
		/* Ensure enough space for decoding */
		if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE)
		{
			mdecoder->decoded_size_max = mdecoder->decoded_size_max * 2 + 16;
			mdecoder->decoded_data = xrealloc(mdecoder->decoded_data, mdecoder->decoded_size_max);
			dst = (uint8*) (((uintptr_t)mdecoder->decoded_data + 15) & ~ 0x0F);
			if (dst - mdecoder->decoded_data != dst_offset)
			{
				/* re-align the memory if the alignment has changed after realloc */
				memmove(dst, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
				dst_offset = dst - mdecoder->decoded_data;
			}
			dst += mdecoder->decoded_size;
		}
		frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size;
#if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20)
		len = avcodec_decode_audio2(mdecoder->codec_context,
			(int16_t*) dst, &frame_size,
			src, src_size);
#else
		{
			AVPacket pkt;
			av_init_packet(&pkt);
			pkt.data = (uint8*) src;
			pkt.size = src_size;
			len = avcodec_decode_audio3(mdecoder->codec_context,
				(int16_t*) dst, &frame_size, &pkt);
		}
#endif
		if (len <= 0 || frame_size <= 0)
		{
			DEBUG_WARN("error decoding");
			break;
		}
		src += len;
		src_size -= len;
		mdecoder->decoded_size += frame_size;
		dst += frame_size;
	}

	if (mdecoder->decoded_size == 0)
	{
		xfree(mdecoder->decoded_data);
		mdecoder->decoded_data = NULL;
	}
	else if (dst_offset)
	{
		/* move the aligned decoded data to original place */
		memmove(mdecoder->decoded_data, mdecoder->decoded_data + dst_offset, mdecoder->decoded_size);
	}

	DEBUG_DVC("data_size %d decoded_size %d",
		data_size, mdecoder->decoded_size);

	return True;
}
예제 #30
0
static int
tsmf_ffmpeg_decode_audio(ITSMFDecoder * decoder, const uint8 * data, uint32 data_size, uint32 extensions)
{
	TSMFFFmpegDecoder * mdecoder = (TSMFFFmpegDecoder *) decoder;
	int len;
	int frame_size;
	uint32 src_size;
	const uint8 * src;
	uint8 * dst;

#if 0
	LLOGLN(0, ("tsmf_ffmpeg_decode_audio: data_size %d", data_size));
	int i;
	for (i = 0; i < data_size; i++)
	{
		LLOG(0, ("%02X ", data[i]));
		if (i % 16 == 15)
			LLOG(0, ("\n"));
	}
	LLOG(0, ("\n"));
#endif

	if (mdecoder->decoded_size_max == 0)
		mdecoder->decoded_size_max = AVCODEC_MAX_AUDIO_FRAME_SIZE;
	mdecoder->decoded_data = malloc(mdecoder->decoded_size_max);
	dst = mdecoder->decoded_data;
	src = data;
	src_size = data_size;

	while (src_size > 0)
	{
		/* Ensure enough space for decoding */
		if (mdecoder->decoded_size_max - mdecoder->decoded_size < AVCODEC_MAX_AUDIO_FRAME_SIZE)
		{
			mdecoder->decoded_size_max *= 2;
			mdecoder->decoded_data = realloc(mdecoder->decoded_data, mdecoder->decoded_size_max);
			dst = mdecoder->decoded_data + mdecoder->decoded_size;
		}
		frame_size = mdecoder->decoded_size_max - mdecoder->decoded_size;
#if LIBAVCODEC_VERSION_MAJOR < 52 || (LIBAVCODEC_VERSION_MAJOR == 52 && LIBAVCODEC_VERSION_MINOR <= 20)
		len = avcodec_decode_audio2(mdecoder->codec_context,
			(int16_t *) dst, &frame_size,
			src, src_size);
#else
		{
			AVPacket pkt;
			av_init_packet(&pkt);
			pkt.data = (uint8 *) src;
			pkt.size = src_size;
			len = avcodec_decode_audio3(mdecoder->codec_context,
				(int16_t *) dst, &frame_size, &pkt);
		}
#endif
		if (len <= 0 || frame_size <= 0)
		{
			LLOGLN(0, ("tsmf_ffmpeg_decode_audio: erro decoding"));
			break;
		}
		src += len;
		src_size -= len;
		mdecoder->decoded_size += frame_size;
		dst += frame_size;
	}

	if (mdecoder->decoded_size == 0)
	{
		free(mdecoder->decoded_data);
		mdecoder->decoded_data = NULL;
	}

	LLOGLN(10, ("tsmf_ffmpeg_decode_audio: data_size %d decoded_size %d",
		data_size, mdecoder->decoded_size));

	return 0;
}