//--------------------------------------------------------------------------- size_t Reader_libmms::Format_Test(MediaInfo_Internal* MI, const String &File_Name) { //Opening the file mmsx_t* Handle=mmsx_connect(0, 0, Ztring(File_Name).To_Local().c_str(), (int)-1); if (Handle==NULL) return 0; mms_off_t Offset=mmsx_seek(0, Handle, 0, SEEK_SET); uint32_t Length=mmsx_get_length(Handle); //Buffer size_t Buffer_Size_Max=Buffer_NormalSize; int8u* Buffer=new int8u[Buffer_Size_Max]; //Parser MI->Open_Buffer_Init(Length, File_Name); //Test the format with buffer bool StopAfterFilled=MI->Config.File_StopAfterFilled_Get(); std::bitset<32> Status; do { //Seek (if needed) if (MI->Open_Buffer_Continue_GoTo_Get()!=(int64u)-1) { if (MI->Open_Buffer_Continue_GoTo_Get()>=Length) break; //Seek requested, but on a file bigger in theory than what is in the real file, we can't do this if (mmsx_seek(0, Handle, mms_off_t(MI->Open_Buffer_Continue_GoTo_Get()), SEEK_SET)!=MI->Open_Buffer_Continue_GoTo_Get()) break; //File is not seekable MI->Open_Buffer_Init((int64u)-1, MI->Open_Buffer_Continue_GoTo_Get()); } //Buffering size_t Buffer_Size=mmsx_read(0, Handle, (char*)Buffer, (int)Buffer_Size_Max); if (Buffer_Size==0) break; //Problem while reading //Parser Status=MI->Open_Buffer_Continue(Buffer, Buffer_Size); } while (!(Status[File__Analyze::IsFinished] || (StopAfterFilled && Status[File__Analyze::IsFilled]))); if (Length==0) //If Size==0, Status is never updated Status=MI->Open_Buffer_Continue(NULL, 0); //File mmsx_close(Handle); //Buffer delete[] Buffer; //Buffer=NULL; //Is this file detected? if (!Status[File__Analyze::IsAccepted]) return 0; MI->Open_Buffer_Finalize(); return 1; }
static GstFlowReturn gst_mms_create (GstPushSrc * psrc, GstBuffer ** buf) { GstMMS *mmssrc; guint8 *data; guint blocksize; gint result; mms_off_t offset; *buf = NULL; mmssrc = GST_MMS (psrc); offset = mmsx_get_current_pos (mmssrc->connection); /* Check if a seek perhaps has wrecked our connection */ if (offset == -1) { GST_DEBUG_OBJECT (mmssrc, "connection broken (probably an error during mmsx_seek_time during a convert query) returning FLOW_ERROR"); return GST_FLOW_ERROR; } /* Choose blocksize best for optimum performance */ if (offset == 0) blocksize = mmsx_get_asf_header_len (mmssrc->connection); else blocksize = mmsx_get_asf_packet_len (mmssrc->connection); *buf = gst_buffer_new_and_alloc (blocksize); data = GST_BUFFER_DATA (*buf); GST_BUFFER_SIZE (*buf) = 0; GST_LOG_OBJECT (mmssrc, "reading %d bytes", blocksize); result = mmsx_read (NULL, mmssrc->connection, (char *) data, blocksize); /* EOS? */ if (result == 0) goto eos; GST_BUFFER_OFFSET (*buf) = offset; GST_BUFFER_SIZE (*buf) = result; GST_LOG_OBJECT (mmssrc, "Returning buffer with offset %" G_GINT64_FORMAT " and size %u", GST_BUFFER_OFFSET (*buf), GST_BUFFER_SIZE (*buf)); gst_buffer_set_caps (*buf, GST_PAD_CAPS (GST_BASE_SRC_PAD (mmssrc))); return GST_FLOW_OK; eos: { GST_DEBUG_OBJECT (mmssrc, "EOS"); gst_buffer_unref (*buf); *buf = NULL; return GST_FLOW_UNEXPECTED; } }
void MMSStreamReader::run() { int to_read = 1024; char prebuf[to_read]; m_handle = mmsx_connect (0, 0, m_url.toLocal8Bit().constData(), 128 * 1024); if(!m_handle) { qWarning("MMSStreamReader: connection failed"); setErrorString("connection failed"); emit error(); QIODevice::close(); return; } m_mutex.lock(); if(m_aborted) { m_mutex.unlock(); qDebug("MMSStreamReader: aborted"); return; } m_mutex.unlock(); qint64 len = 0; forever { m_mutex.lock(); if(m_buffer_at + to_read > m_buffer_size) { m_buffer_size = m_buffer_at + to_read; m_buffer = (char *)realloc(m_buffer, m_buffer_size); } m_mutex.unlock(); len = mmsx_read (0, m_handle, prebuf, to_read); m_mutex.lock(); if(len < 0) { m_mutex.unlock(); qWarning("MMSStreamReader: mms thread funished with code %lld (%s)", len, strerror(len)); if(!m_aborted && !m_ready) { setErrorString(strerror(len)); emit error(); } break; } memcpy(m_buffer + m_buffer_at, prebuf, len); m_buffer_at += len; if(!m_ready) checkBuffer(); m_mutex.unlock(); if(m_aborted) break; DownloadThread::usleep(5000); } QIODevice::close(); }
static GstFlowReturn gst_mms_create (GstPushSrc * psrc, GstBuffer ** buf) { GstMMS *mmssrc = GST_MMS (psrc); guint8 *data; guint blocksize; gint result; mms_off_t offset; *buf = NULL; offset = mmsx_get_current_pos (mmssrc->connection); /* Check if a seek perhaps has wrecked our connection */ if (offset == -1) { GST_ERROR_OBJECT (mmssrc, "connection broken (probably an error during mmsx_seek_time during a convert query) returning FLOW_ERROR"); return GST_FLOW_ERROR; } /* Choose blocksize best for optimum performance */ if (offset == 0) blocksize = mmsx_get_asf_header_len (mmssrc->connection); else blocksize = mmsx_get_asf_packet_len (mmssrc->connection); data = g_try_malloc (blocksize); if (!data) { GST_ERROR_OBJECT (mmssrc, "Failed to allocate %u bytes", blocksize); return GST_FLOW_ERROR; } GST_LOG_OBJECT (mmssrc, "reading %d bytes", blocksize); result = mmsx_read (NULL, mmssrc->connection, (char *) data, blocksize); /* EOS? */ if (result == 0) goto eos; *buf = gst_buffer_new_wrapped (data, result); GST_BUFFER_OFFSET (*buf) = offset; GST_LOG_OBJECT (mmssrc, "Returning buffer with offset %" G_GINT64_FORMAT " and size %u", offset, result); return GST_FLOW_OK; eos: { GST_DEBUG_OBJECT (mmssrc, "EOS"); g_free (data); *buf = NULL; return GST_FLOW_EOS; } }
static size_t mms_read (void *ptr, size_t size, size_t nmemb, DB_FILE *stream) { assert (stream); assert (ptr); int connect_err = mms_ensure_connected ((MMS_FILE *)stream); if (connect_err < 0) { return connect_err; } MMS_FILE *fp = (MMS_FILE *)stream; int res = mmsx_read ((mms_io_t *)fp->io, fp->stream, ptr, size * nmemb); fp->pos += res; if (fp->need_abort) { return -1; } return res; }
//--------------------------------------------------------------------------- size_t Reader_libmms::Format_Test(MediaInfo_Internal* MI, const String &File_Name) { mmsx_t* Handle; //Opening the file #if MEDIAINFO_LIBMMS_DESCRIBE_SUPPORT if (MI->Config.File_Mmsh_Describe_Only_Get()) { // Use MMSH & Send a DESCRIBE request mmsh_t* MmshHandle; MmshHandle=mmsh_describe_request(0, 0, Ztring(File_Name).To_Local().c_str()); if (MmshHandle==NULL) return 0; Handle=mmsx_set_mmsh_handle(MmshHandle); if (Handle==NULL) { mmsh_close(MmshHandle); return 0; } } else #endif //MEDIAINFO_LIBMMS_DESCRIBE_SUPPORT { // Use MMS or MMSH (Send a DESCRIBE & PLAY request) Handle=mmsx_connect(0, 0, Ztring(File_Name).To_Local().c_str(), (int)-1); if (Handle==NULL) return 0; } //Init size_t Buffer_Size_Max; uint32_t Length; if (!MI->Config.File_Mmsh_Describe_Only_Get()) { //Buffer Buffer_Size_Max=Buffer_NormalSize; //MediaInfo init mms_off_t Offset=mmsx_seek(0, Handle, 0, SEEK_SET); uint32_t Length=mmsx_get_length(Handle); MI->Open_Buffer_Init(Length, File_Name); } else { //Buffer Buffer_Size_Max=mmsx_get_asf_header_len(Handle); //MediaInfo init Length=(uint32_t)-1; MI->Open_Buffer_Init((int64u)-1, File_Name); } int8u* Buffer=new int8u[Buffer_Size_Max]; //Test the format with buffer bool StopAfterFilled=MI->Config.File_StopAfterFilled_Get(); std::bitset<32> Status; do { //Seek (if needed) if (MI->Open_Buffer_Continue_GoTo_Get()!=(int64u)-1) { if (MI->Open_Buffer_Continue_GoTo_Get()>=Length) break; //Seek requested, but on a file bigger in theory than what is in the real file, we can't do this if (mmsx_seek(0, Handle, mms_off_t(MI->Open_Buffer_Continue_GoTo_Get()), SEEK_SET)!=MI->Open_Buffer_Continue_GoTo_Get()) break; //File is not seekable MI->Open_Buffer_Init((int64u)-1, MI->Open_Buffer_Continue_GoTo_Get()); } //Buffering size_t Buffer_Size; if (!MI->Config.File_Mmsh_Describe_Only_Get()) Buffer_Size=mmsx_read(0, Handle, (char*)Buffer, (int)Buffer_Size_Max); else Buffer_Size=mmsx_peek_header(Handle, (char*)Buffer, (int)Buffer_Size_Max); //Parser Status=MI->Open_Buffer_Continue(Buffer, Buffer_Size); if (Buffer_Size==0 || MI->Config.File_Mmsh_Describe_Only_Get()) break; } while (!(Status[File__Analyze::IsFinished] || (StopAfterFilled && Status[File__Analyze::IsFilled]))); //File mmsx_close(Handle); //Buffer delete[] Buffer; //Buffer=NULL; //Is this file detected? if (!Status[File__Analyze::IsAccepted]) return 0; MI->Open_Buffer_Finalize(); return 1; }