Ejemplo n.º 1
0
/*
 * Input	:	Filename
 * Output	: 	1 if succesful 0 if not
 */
int openFile(const char * name)
{
	readOff = readBuf;
	if((fp = fopen(name, "rb"))) {
		if(strstr(name, ".aac") || strstr(name, ".AAC")) {
			dec_state  = DEC_AAC;
			if((decoder = AACInitDecoder())) {
				if(fill_readBuffer(readBuf, &readOff, READ_BUF_SIZE, &dataLeft) == READ_BUF_SIZE) {
					int ret = 0;
					int bitOffset = 0, bitsAvail = dataLeft << 3;
					if(IS_ADIF(readBuf))
						ret = UnpackADIFHeader((AACDecInfo*)decoder, &readOff, &bitOffset, &bitsAvail);
					else
						ret = UnpackADTSHeader((AACDecInfo*)decoder, &readOff, &bitOffset, &bitsAvail);
					if(!ret) {
						AACGetLastFrameInfo(decoder, &inf);
						readOff = readBuf;
						dataLeft = READ_BUF_SIZE;
						return 1;
					}
				}
			}
		} else {
			dec_state = DEC_MP4;
			mp4cb.user_data = fp;
			if((infile = mp4ff_open_read(&mp4cb))) {
				if ((track = findAudioTrack(infile)) >= 0) {
					/* Decoder failed to initialize */
					if((decoder = AACInitDecoder())) {
						/* Decoder should be updated to decode raw blocks in the mp4
						 * IMPORTANT:
						 * mp4ff_get_channel_count will return the wrong value for mono in this state
						 */
						inf.sampRateCore = mp4ff_get_sample_rate(infile, track);
						samples = mp4ff_num_samples(infile, track);
						/*
						DECODER CONFIG:
						[AAAA ABBB] [BCCC CDEF]

						A)object type
						B)frequency index
						C)channel configuration
						D)bit: frame length flag
						E)bit: dependsOnCoreCoder
						F)bit: extensionFlag
						*/

						unsigned char * config_buf;
						unsigned int config_bufSize;
						mp4ff_get_decoder_config(infile, track, &config_buf, &config_bufSize);
						inf.profile =  AAC_PROFILE_LC;
						inf.nChans 	= (config_buf[1] >> 3) & 0xF;
						free(config_buf);
						if(!AACSetRawBlockParams(decoder, 0, &inf))
							return 1;
					}
				}
			}
		}
	}
Ejemplo n.º 2
0
ReadStatus MP4Reader::parse() {
  mp4AudioSpecificConfig cfg;
  FXuchar* buffer;
  FXuint   size;
  FXint    ntracks;

  FXASSERT(handle==NULL);
  FXASSERT(packet);

  handle = mp4ff_open_read(&callback);
  if (handle==NULL)
    goto error;

  ntracks = mp4ff_total_tracks(handle);
  if (ntracks<=0)
    goto error;

  for (FXint i=0;i<ntracks;i++) {
    if ((mp4ff_get_decoder_config(handle,i,&buffer,&size)==0) && buffer && size) {
      if (NeAACDecAudioSpecificConfig(buffer,size,&cfg)==0) {

        af.set(AP_FORMAT_S16,mp4ff_get_sample_rate(handle,i),mp4ff_get_channel_count(handle,i));
        af.debug();

        if (size>packet->space()) {
          GM_DEBUG_PRINT("MP4 config buffer is too big for decoder packet");
          free(buffer);
          goto error;
          }

        track=i;
        frame=0;
        nframes=mp4ff_num_samples(handle,i);
        stream_length=mp4ff_get_track_duration(handle,i);


        packet->append(buffer,size);
        packet->flags|=AAC_FLAG_CONFIG|AAC_FLAG_FRAME;
        engine->decoder->post(new ConfigureEvent(af,Codec::AAC));

        send_meta();

        engine->decoder->post(packet);

        packet=NULL;
        flags|=FLAG_PARSED;
        free(buffer);
        return ReadOk;
        }
      free(buffer);
      }
    }

error:
  packet->unref();
  return ReadError;
  }
Ejemplo n.º 3
0
Archivo: mp4.c Proyecto: chrippa/xmms2
static int
xmms_mp4_get_track (xmms_xform_t *xform, mp4ff_t *infile)
{
	glong chans, rate;
	int i;
	int numTracks = mp4ff_total_tracks (infile);

	/* find first suitable audio track */
	for (i = 0; i < numTracks; i++) {
		gint object_type = mp4ff_get_audio_type (infile, i);

		/* these identifiers are mostly from VLC code */
		switch (object_type) {
		case 0x40: /* MPEG-4 audio */
		case 0x66: /* MPEG-2 AAC */
		case 0x67: /* MPEG-2 AAC LC */
		case 0x68: /* MPEG-2 AAC SSR */
			xmms_xform_outdata_type_add (xform,
			                             XMMS_STREAM_TYPE_MIMETYPE,
			                             "audio/aac",
			                             XMMS_STREAM_TYPE_END);
			return i;
		case 0x69: /* MPEG-2 audio */
		case 0x6B: /* MPEG-1 audio */
			continue;
		case 0xff: /* ALAC */
			chans = mp4ff_get_channel_count (infile, i);
			rate = mp4ff_get_sample_rate (infile, i);
			if (chans <= 0 || rate <= 0) {
				XMMS_DBG ("Bad ALAC audio track %d", i);
				continue;
			}
			xmms_xform_outdata_type_add (xform,
			                             XMMS_STREAM_TYPE_MIMETYPE,
			                             "audio/x-ffmpeg-alac",
			                             XMMS_STREAM_TYPE_FMT_SAMPLERATE,
			                             (int)rate,
			                             XMMS_STREAM_TYPE_FMT_CHANNELS,
			                             (int)chans,
			                             XMMS_STREAM_TYPE_END);
			return i;
		default:
			continue;
		}
	}

	/* can't decode this */
	return -1;
}
Ejemplo n.º 4
0
static void
xmms_mp4_get_mediainfo (xmms_xform_t *xform)
{
	xmms_mp4_data_t *data;
	const gchar *metakey;
	glong temp;
	gint i, num_items;

	g_return_if_fail (xform);

	data = xmms_xform_private_data_get (xform);
	g_return_if_fail (data);

	if ((temp = mp4ff_get_sample_rate (data->mp4ff, data->track)) > 0) {
		glong srate = temp;

		if ((temp = mp4ff_get_track_duration (data->mp4ff, data->track)) >= 0) {
			glong msec = ((gint64) temp) * 1000 / srate;

			metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_DURATION,
			xmms_xform_metadata_set_int (xform, metakey, msec);
		}
	}

	if ((temp = mp4ff_get_avg_bitrate (data->mp4ff, data->track)) >= 0) {
		metakey = XMMS_MEDIALIB_ENTRY_PROPERTY_BITRATE;
		xmms_xform_metadata_set_int (xform, metakey, temp);
	}

	num_items = mp4ff_meta_get_num_items (data->mp4ff);
	for (i = 0; i < num_items; i++) {
		gchar *key, *value;
		guint length;

		length = mp4ff_meta_get_by_index (data->mp4ff, i, &key, &value);
		if (length > 0) {
			if (!xmms_xform_metadata_mapper_match (xform, key, value, length)) {
				/* iTunSMPB should be handled in xmms_mp4_gapless_try */
				if (0 != g_ascii_strcasecmp (key, "iTunSMPB")) {
					XMMS_DBG ("Unhandled tag '%s' = '%s'", key, value);
				}
			}
			g_free (key);
			g_free (value);
		}
	}
}
Ejemplo n.º 5
0
/*
 * Input	:	Filename
 * Output	: 	1 if succesful -1 if not
 */
int mp4_openFile(char * name) {
	if((sndFile = fopen(name, "rb"))) {
		mp4cb.user_data = sndFile;
		if((infile = mp4ff_open_read(&mp4cb))) {
			if ((track = findAudioTrack(infile)) >= 0) {
				/* Decoder failed to initialize */
				if((decoder = AACInitDecoder())) {
					/* Decoder should be updated to decode raw blocks in the mp4 */
					inf.sampRateCore = mp4ff_get_sample_rate(infile, track);
					inf.nChans = mp4ff_get_channel_count(infile,track);
					/* AACSetRawBlockParams will fail if not set */
					inf.profile = AAC_PROFILE_LC;
					samples = mp4ff_num_samples(infile, track);
					if(!AACSetRawBlockParams(decoder, 0, &inf))
						return 0;
				}
			}
		}
	}
	return -1;	/* sndFile == NULL */
}
Ejemplo n.º 6
0
// returns -1 for error, 0 for mp4, 1 for aac
int
aac_probe (DB_FILE *fp, const char *fname, MP4FILE_CB *cb, float *duration, int *samplerate, int *channels, int *totalsamples, int *mp4track, MP4FILE *pmp4) {
    // try mp4

    if (mp4track) {
        *mp4track = -1;
    }
    if (*pmp4) {
        *pmp4 = NULL;
    }
    *duration = -1;
#ifdef USE_MP4FF
    mp4ff_t *mp4 = mp4ff_open_read (cb);
#else
    MP4FileHandle mp4 = MP4ReadProvider (fname, 0, cb);
#endif
    if (!mp4) {
        trace ("not an mp4 file\n");
        return -1;
    }
    if (pmp4) {
        *pmp4 = mp4;
    }
#ifdef USE_MP4FF
    int ntracks = mp4ff_total_tracks (mp4);
    if (ntracks > 0) {
        trace ("m4a container detected, ntracks=%d\n", ntracks);
        int i = -1;
        trace ("looking for mp4 data...\n");
        int sr = -1;
        for (i = 0; i < ntracks; i++) {
            unsigned char*  buff = 0;
            unsigned int    buff_size = 0;
            mp4AudioSpecificConfig mp4ASC;
            mp4ff_get_decoder_config(mp4, i, &buff, &buff_size);
            if(buff){
                int rc = AudioSpecificConfig(buff, buff_size, &mp4ASC);
                sr = mp4ASC.samplingFrequency;
                free(buff);
                if(rc < 0)
                    continue;
                break;
            }
        }

        if (i != ntracks) 
        {
            trace ("mp4 track: %d\n", i);
            if (sr != -1) {
                *samplerate = sr;
            }
            else {
                *samplerate = mp4ff_get_sample_rate (mp4, i);
            }
            *channels = mp4ff_get_channel_count (mp4, i);
            int samples = mp4ff_num_samples(mp4, i) * 1024;
            samples = (int64_t)samples * (*samplerate) / mp4ff_time_scale (mp4, i);

            trace ("mp4 nsamples=%d, samplerate=%d, timescale=%d, duration=%lld\n", samples, *samplerate, mp4ff_time_scale(mp4, i), mp4ff_get_track_duration(mp4, i));
            *duration = (float)samples / (*samplerate);

            if (totalsamples) {
                *totalsamples = samples;
            }
            if (mp4track) {
                *mp4track = i;
            }
            if (!*pmp4) {
                mp4ff_close (mp4);
            }
            return 0;
        }
    }
#else
    MP4FileHandle mp4File = mp4;
    MP4TrackId trackId = MP4FindTrackId(mp4File, 0, "audio", 0);
    trace ("trackid: %d\n", trackId);
    uint32_t timeScale = MP4GetTrackTimeScale(mp4File, trackId);
    MP4Duration trackDuration = MP4GetTrackDuration(mp4File, trackId);
    MP4SampleId numSamples = MP4GetTrackNumberOfSamples(mp4File, trackId);
    u_int8_t* pConfig;
    uint32_t configSize = 0;
    bool res = MP4GetTrackESConfiguration(mp4File, trackId, &pConfig, &configSize);
    if (res && pConfig) {
        mp4AudioSpecificConfig mp4ASC;
        int rc = AudioSpecificConfig(pConfig, configSize, &mp4ASC);
        free (pConfig);
        if (rc >= 0) {
            *samplerate = mp4ASC.samplingFrequency;
            *channels = MP4GetTrackAudioChannels (mp4File, trackId);
//            int64_t duration = MP4ConvertFromTrackDuration (mp4File, trackId, trackDuration, timeScale);
            int samples = MP4GetTrackNumberOfSamples (mp4File, trackId) * 1024 * (*channels);
            trace ("mp4 nsamples=%d, timescale=%d, samplerate=%d\n", samples, timeScale, *samplerate);
            *duration = (float)samples / (*samplerate);

            if (totalsamples) {
                *totalsamples = samples;
            }
            if (mp4track) {
                *mp4track = trackId;
            }
            if (!*pmp4) {
                MP4Close (mp4);
            }
            return 0;
        }
    }
#endif
    if (*pmp4) {
        *pmp4 = NULL;
    }

    if (mp4) {
#if USE_MP4FF
        mp4ff_close (mp4);
#else
        MP4Close (mp4);
#endif
        mp4 = NULL;
    }
    trace ("mp4 track not found, looking for aac stream...\n");

    // not an mp4, try raw aac
#if USE_MP4FF
    deadbeef->rewind (fp);
#endif
    if (parse_aac_stream (fp, samplerate, channels, duration, totalsamples) == -1) {
        trace ("aac stream not found\n");
        return -1;
    }
    trace ("found aac stream\n");
    return 1;
}