Esempio n. 1
0
void
MoonVDADecoder::OpenDecoderAsyncInternal ()
{
	IMediaStream *stream = GetStream ();
	VideoStream *vs = (VideoStream *) stream;
	int format = 'avc1';

	CFDataRef avcCData = CFDataCreate (kCFAllocatorDefault, (const uint8_t*) stream->GetRawExtraData (), stream->GetRawExtraDataSize ());
	OSStatus status = CreateDecoder ((SInt32) vs->GetHeight (), (SInt32) vs->GetWidth (), (OSType) format, avcCData);

	if (avcCData) CFRelease (avcCData);

	if (status == kVDADecoderNoErr) {
		SetPixelFormat (MoonPixelFormat422YpCbCr8);

		ReportOpenDecoderCompleted ();
	} else {
		char *str = g_strdup_printf ("MoonVDADecoder failed to open codec (result: %d)", status);
		ReportErrorOccurred (str);
		g_free (str);
	}
}
Esempio n. 2
0
void
Mp3Demuxer::OpenDemuxer (MemoryBuffer *open_source)
{
	LOG_MP3 ("Mp3Demuxer::OpenDemuxer ()\n");

	IMediaStream **streams = NULL;
	IMediaStream *stream;
	MpegFrameHeader mpeg;
	gint64 stream_start;
	AudioStream *audio;
	Media *media;
	guint8 buffer [10];
	MpegVBRHeader vbr;
	guint64 duration;
	guint32 size = 0;
	double nframes;
	int stream_count;
	double len;
	gint64 end;
	int i;

	if (open_source == NULL) {
		/* No data read yet, request a read */
		if (!RequestMoreData (OpenDemuxerCallback))
			ReportErrorOccurred ("Could not open Mp3 demuxer: unexpected end of data.");
		return;
	}

	if (open_source->GetSize () < 10) {
		/* Not enough data read, request more */
		if (!RequestMoreData (OpenDemuxerCallback))
			ReportErrorOccurred ("Could not open Mp3 demuxer: data stream ended early.");
		return;
	}
	
	if (!open_source->Peek (buffer, 10)) {
		/* This shouldn't fail */
		ReportErrorOccurred ("Could not open Mp3 demuxer: peek error.");
		return;
	}

	// Check for a leading ID3 tag
	if (!strncmp ((const char *) buffer, "ID3", 3)) {
		for (i = 0; i < 4; i++) {
			if (buffer[6 + i] & 0x80) {
				ReportErrorOccurred ("Could not open Mp3 demuxer: invalid ID3 tag.");
				return;
			}
			
			size = (size << 7) | buffer[6 + i];
		}
		
		if ((buffer[5] & (1 << 4))) {
			// add additional 10 bytes for footer
			size += 20;
		} else
			size += 10;
		
		// MPEG stream data starts at the end of the ID3 tag
		stream_start = (gint64) size;
	} else {
		stream_start = 0;
	}
	
	/* Seek to the stream start */
	if (stream_start > 0) {
		/* We're still at position 0, so no need to do anything if stream_start is also 0 */
		if (stream_start > open_source->GetSize ()) {
			/* Not enough data, request more */
			if (!RequestMoreData (OpenDemuxerCallback)) {
				ReportErrorOccurred ("Could not open Mp3 demuxer: could not seek to end of ID3 tag.");
				return;
			}
		}
		open_source->SeekOffset (stream_start);
	}

	// There can be an "arbitrary" amount of garbage at the
	// beginning of an mp3 stream, so we need to find the first
	// MPEG sync header by scanning.
	vbr.type = MpegNoVBRHeader;
	if (!Mp3FrameReader::FindMpegHeader (&mpeg, &vbr, open_source)) {
		/* Could not find a header with the available data */
		/* Seek back to 0, read more data, and try again */
		/* TODO: store the current state and only read new data to avoid seeking back here */
		open_source->SeekSet (0);
		if (!RequestMoreData (OpenDemuxerCallback)) {
			/* This should not happen, we should be able to seek back to 0 */
			ReportErrorOccurred ("Could not open Mp3 demuxer: error while seeking to start point.");
		}
		
		return;
	}

	if (vbr.type == MpegNoVBRHeader) {
		// calculate the frame length
		len = mpeg_frame_length (&mpeg);
		
		if ((end = source->GetSize ()) != -1) {
			// estimate the number of frames
			nframes = ((double) end - (double) stream_start) / (double) len;
		} else {
			nframes = 0;
		}
	} else {
		// calculate the frame length
		len = mpeg_frame_length (&mpeg);
		nframes = vbr.nframes;
	}
	
	// calculate the duration of the first frame
	duration = mpeg_frame_duration (&mpeg);
	
	media = GetMediaReffed ();	
	stream = audio = new AudioStream (media);
	media->unref ();
	media = NULL;
	reader = new Mp3FrameReader (this, source, audio, stream_start, len, duration, nframes);
	
	audio->SetCodecId (CODEC_MP3);
	audio->SetDuration (duration * nframes);
	audio->SetBitRate (mpeg.bit_rate);
	audio->SetChannels (mpeg.channels);
	audio->SetSampleRate (mpeg.sample_rate);
	audio->SetBlockAlign (mpeg_block_size (&mpeg));
	audio->SetBitsPerSample (mpeg.layer == 1 ? 32 : 8);
	audio->SetExtraData (NULL);
	audio->SetExtraDataSize (0);
	
	streams = g_new (IMediaStream *, 2);
	streams[0] = stream;
	streams[1] = NULL;
	stream_count = 1;
	
	SetStreams (streams, stream_count);
	stream->unref ();
	
	this->current_source = open_source;
	this->current_source->ref ();

	LOG_MP3 ("Mp3Demuxer::OpenDemuxer (): Version: %s Layer: %u VBR: %s Duration: %" G_GUINT64_FORMAT " ms Bit rate: %u Channels: %u Sample Rate: %u Block Align: %u Bits per sample: %u Number of frames: %.2f Frame length: %.2f\n",
		mpeg.version == 3 ? "2.5" : (mpeg.version == 2 ? "2" : "1"), mpeg.layer, vbr.type == MpegNoVBRHeader ? "No" : (vbr.type == MpegXingHeader ? "Xing" : "VBRI"), MilliSeconds_FromPts (audio->GetDuration ()), audio->GetBitRate (), audio->GetChannels (), audio->GetSampleRate (), audio->GetBlockAlign (), audio->GetBitsPerSample (), nframes, len);
		
	ReportOpenDemuxerCompleted ();
}