Example #1
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;
  }
Example #2
0
File: mp4.c Project: 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;
}
Example #3
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 */
}
Example #4
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;
}