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); } }
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 (); }