int getFrameLength(MP3Header * pHeader) { int frame_length = -1; if (pHeader->bitrate != 0 /*BR_FREE*/ && pHeader->bitrate != 15 /*BR_BAD*/ && pHeader->frequency != 3/*SF_RESERVED*/) { if (pHeader->layer == LAYER_I) { frame_length = (12 * getBitrate(pHeader) * 1024 / getFrequency(pHeader) + pHeader->padding) * 4; } else if (pHeader->layer == LAYER_II || !(pHeader->version == MPEG_2_0)) { frame_length = 144 * getBitrate(pHeader) * 1000 / getFrequency(pHeader) + pHeader->padding; } else { frame_length = 72 * getBitrate(pHeader) * 1000 / getFrequency(pHeader) + pHeader->padding; } } return frame_length; }
int CMP3Info::getLengthInSeconds() { // kiloBitFileSize to match kiloBitPerSecond in bitrate... int kiloBitFileSize = (8 * fileSize) / 1000; return (int)(kiloBitFileSize/getBitrate()); }
QString TrackInfoObject::getBitrateStr() const { return QString("%1").arg(getBitrate()); }
void Track::writeData( QByteArray& data) const { QBuffer buffer( data); buffer.open(IO_WriteOnly); QDataStream stream( &buffer); stream.setByteOrder( QDataStream::LittleEndian); /** Write the track header **/ stream << (Q_UINT32) 0x7469686D; // 0x00 mhit stream << (Q_UINT32) 0xf4; // 0x04 headerlen stream << (Q_UINT32) 0x0; // 0x08 length - set later stream << (Q_UINT32) 0x0; // 0x0C number of mhods stream << (Q_UINT32) getID(); // 0x10 stream << (Q_UINT32) 1; // 0x14 //stream << (Q_UINT32) 0; // 0x18 stream << (Q_UINT32) 0x4d503320; // ipod shiffle wants a "MP3 " here stream << vbr; // 0x1C stream << type; // 0x1D stream << compilation; // 0x1E stream << rating; // 0x1F stream << (Q_UINT32) getLastModified()+ MAC_EPOCH_DELTA; // 0x20 stream << (Q_UINT32) getFileSize(); // 0x24 stream << (Q_UINT32) getTrackLength(); // 0x28 stream << (Q_UINT32) getTrackNumber(); // 0x2C stream << (Q_UINT32) getTrackCount(); // 0x30 stream << (Q_UINT32) getYear(); // 0x34 stream << (Q_UINT32) getBitrate(); // 0x38 stream << (Q_UINT32) getSamplerate(); // 0x3C stream << (Q_UINT32) getVolumeAdjust(); // 0x40 stream << (Q_UINT32) 0; // 0x44 empty space //stream << (Q_UINT32) getTrackLength(); // 0x48 empty space stream << (Q_UINT32) 0; // 0x48 empty space stream << (Q_UINT32) 0; // 0x4C empty space stream << (Q_UINT32) getPlayCount(); // 0x50 stream << (Q_UINT32) getPlayCount(); // 0x54 stream << (Q_UINT32) getLastPlayed(); // 0x58 stream << (Q_UINT32) getCdNumber(); // 0x5C stream << (Q_UINT32) getCdCount(); // 0x60 stream << (Q_UINT32) 0; // 0x64 empty space //userid from apple store stream << (Q_UINT32) date_added; // 0x68 stream << (Q_UINT32) 0; // boockmarktime stream << (Q_UINT64) dbid; // unique bit (64 bit) stream << (Q_UINT8) 0; // checked in iTZnes stream << (Q_UINT8) 0; // application rating stream << (Q_UINT16) 0; // BPM stream << (Q_UINT16) 0; // artworkcount stream << (Q_UINT16) 0xffff; // unkown stream << (Q_UINT32) 0; // artwork size stream << (Q_UINT32) 0; // unkown stream << (float) -getSamplerate(); // samplerate as floating point "-"?!? stream << (Q_UINT32) 0; // date/time added stream << (Q_UINT32) file_format_code; // unkown, but 0x0000000c for MP3 ? stream << (Q_UINT32) 0; // unkown stream << (Q_UINT32) 0; // unkown stream << (Q_UINT32) 0; // unkown stream << (Q_UINT32) 0; // unkown stream << (Q_UINT32) 0x02; // unknown stream << (Q_UINT64) dbid; // same unique id as above for( int i= 0; i< 17; i++) stream << (Q_UINT32) 0; /** Write Track contents **/ Q_UINT32 num_mhods = 0; for( PropertyMap::const_iterator element= properties.begin(); element!= properties.end(); ++element) { if( (*element).isEmpty()) continue; const char *data= (const char *)(*element).ucs2(); if( data == NULL) continue; int datalen= 2* (*element).length(); stream << (Q_UINT32) 0x646F686D; // mhod stream << (Q_UINT32) 0x18; // headerlen stream << (Q_UINT32) 40+ datalen; stream << (Q_UINT32) element.key(); stream << (Q_UINT32) 0; stream << (Q_UINT32) 0; stream << (Q_UINT32) 1; // dummy - would refer to the trackID if used in playlist stream << (Q_UINT32) datalen; stream << (Q_UINT32) 0; stream << (Q_UINT32) 0; stream.writeRawBytes( data, datalen); num_mhods++; } buffer.at( 8); stream << (Q_UINT32)data.size(); // set content length stream << (Q_UINT32)num_mhods; // set real mhod count buffer.close(); }
status_t Converter::initEncoder() { AString inputMIME; CHECK(mInputFormat->findString("mime", &inputMIME)); AString outputMIME; bool isAudio = false; if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_AUDIO_RAW)) { if (mIsPCMAudio) { outputMIME = MEDIA_MIMETYPE_AUDIO_RAW; } else { outputMIME = MEDIA_MIMETYPE_AUDIO_AAC; } isAudio = true; } else if (!strcasecmp(inputMIME.c_str(), MEDIA_MIMETYPE_VIDEO_RAW)) { outputMIME = MEDIA_MIMETYPE_VIDEO_AVC; } else { TRESPASS(); } if (!mIsPCMAudio) { mEncoder = MediaCodec::CreateByType( mCodecLooper, outputMIME.c_str(), true /* encoder */); if (mEncoder == NULL) { return ERROR_UNSUPPORTED; } } mOutputFormat = mInputFormat->dup(); if (mIsPCMAudio) { return OK; } mOutputFormat->setString("mime", outputMIME.c_str()); int32_t audioBitrate = getBitrate("media.wfd.audio-bitrate", 128000); int32_t videoBitrate = getBitrate("media.wfd.video-bitrate", 3000000); ALOGI("using audio bitrate of %d bps, video bitrate of %d bps", audioBitrate, videoBitrate); if (isAudio) { mOutputFormat->setInt32("bitrate", audioBitrate); } else { mOutputFormat->setInt32("bitrate", videoBitrate); mOutputFormat->setInt32("bitrate-mode", OMX_Video_ControlRateConstant); mOutputFormat->setInt32("frame-rate", 30); mOutputFormat->setInt32("i-frame-interval", 15); // Iframes every 15 secs // Configure encoder to use intra macroblock refresh mode mOutputFormat->setInt32("intra-refresh-mode", OMX_VIDEO_IntraRefreshCyclic); int width, height, mbs; if (!mOutputFormat->findInt32("width", &width) || !mOutputFormat->findInt32("height", &height)) { return ERROR_UNSUPPORTED; } // Update macroblocks in a cyclic fashion with 10% of all MBs within // frame gets updated at one time. It takes about 10 frames to // completely update a whole video frame. If the frame rate is 30, // it takes about 333 ms in the best case (if next frame is not an IDR) // to recover from a lost/corrupted packet. mbs = (((width + 15) / 16) * ((height + 15) / 16) * 10) / 100; mOutputFormat->setInt32("intra-refresh-CIR-mbs", mbs); } ALOGV("output format is '%s'", mOutputFormat->debugString(0).c_str()); mNeedToManuallyPrependSPSPPS = false; status_t err = NO_INIT; if (!isAudio) { sp<AMessage> tmp = mOutputFormat->dup(); tmp->setInt32("prepend-sps-pps-to-idr-frames", 1); err = mEncoder->configure( tmp, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); if (err == OK) { // Encoder supported prepending SPS/PPS, we don't need to emulate // it. mOutputFormat = tmp; } else { mNeedToManuallyPrependSPSPPS = true; ALOGI("We going to manually prepend SPS and PPS to IDR frames."); } } if (err != OK) { // We'll get here for audio or if we failed to configure the encoder // to automatically prepend SPS/PPS in the case of video. err = mEncoder->configure( mOutputFormat, NULL /* nativeWindow */, NULL /* crypto */, MediaCodec::CONFIGURE_FLAG_ENCODE); } if (err != OK) { return err; } err = mEncoder->start(); if (err != OK) { return err; } err = mEncoder->getInputBuffers(&mEncoderInputBuffers); if (err != OK) { return err; } return mEncoder->getOutputBuffers(&mEncoderOutputBuffers); }
int main(int argc, char* argv[]) { command_line_s commandLine; stream_s *stream = NULL; connection_list_s *connection; int browserListener; fd_set master; fd_set read_fds; int fdmax; int sock; struct timeval tv; char buf[BUF_SIZE]; int ret; int sockcont=0; port_offset = 0; signal(SIGINT, sigINThandler); if (parseCommandLine(argc, argv, &commandLine) < 0) return -1; log = open_log(log, "error.log"); log_msg(log, "Created log file\n"); p_log = open_log(p_log, commandLine.logfile); tv.tv_sec = 60; tv.tv_usec = 0; FD_ZERO(&master); FD_ZERO(&read_fds); log_msg(log, "Server initiated"); /* set up socket to listen for incoming connections from the browser*/ if (setupBrowserListenerSocket(&browserListener, commandLine.listen_port) < 0) return EXIT_FAILURE; /*Add browser listerner to master set of fd's*/ FD_SET(browserListener, &master); fdmax = browserListener; log_msg(log, "Browser listener: %d\n", browserListener); tv.tv_sec = 60; while (1) { //wait for a socket to have data to read sock = waitForAction(&master,&read_fds, fdmax, tv, sockcont);/*blocking*/ if (sock < 0) continue;//select timeout if (sock == 0){//read through read_fs , start from beginning sockcont = 0; continue; } sockcont = sock + 1; log_msg(log, "Browser requesting a new connection\n"); //Browser is requesting new connection if (sock == browserListener){ //new connection if (stream == NULL){ log_msg(log, "Stream is null\n"); } if (acceptBrowserServerConnectionToStream(browserListener, &master, &fdmax, &stream, &commandLine) < 0)//add connection to stream //add browser sock to read_fs return EXIT_FAILURE; //if no current streams } else { log_msg(log, "Determining if connection is from browser or server...\n"); //Determine if coming from browser or server connection = getConnectionFromSocket(stream, sock); if (connection == NULL){ log_msg(log, "Error: NULL connection\n EXIT_FAILURE\n"); return EXIT_FAILURE; } if (sock == connection->browser_sock){ log_msg(log, "Found a browser connection\n"); memset(buf, 0, BUF_SIZE); ret = receive(sock, &master, &fdmax, browserListener, &buf, connection, stream); int x; char *get; char bit[16]; char header[100]; x = strcspn(buf, "\n"); if (x > 99) x = 99; memcpy(header, buf, x); header[x] = '\0'; log_msg(log, "Received request from browser:\n%s\n\n", header); // printf("Received header request from browser:\n%s\n\n", header); if (ret > 0){ //GET request for .f4m file //Send GET for ... _nolist.f4m if ((get = strstr(header, "big_buck_bunny.f4m")) != NULL){ stream->current_throughput = getBitrate(stream->current_throughput, stream->available_bitrates); unsigned int index = strstr(buf, ".f4m") - buf; ret = replaceString(buf, ret, "_nolist", index, 0, strlen("_nolist") ); // printf("buf:%s\n", buf); } //Get request is for /vod/###SegX-FragY //Modify for current tput and start new chunk if ((get = strstr(header, "Seg")) != NULL){ // /vod/###SegX-FragY char *chunkName; char chunk[64]; chunkName = strstr(buf, "/vod/"); int intLen = strstr(buf, "Seg") - (chunkName + strlen("/vod/")); unsigned int index = 0; int br = getBitrate(stream->current_throughput, stream->available_bitrates); //### // printf("cur tput: %d, found br: %d\n", stream->current_throughput, br); snprintf(bit, 16, "%d", br); //convert br into string ret = replaceString(chunkName + strlen("/vod/"), ret, bit, index, intLen, strlen(bit)); memcpy(chunk, chunkName, strstr(buf, " HTTP") - chunkName); chunk[strstr(buf, " HTTP") - chunkName] = '\0'; // printf("Chunkname sent to start chunk: %s\n", chunk); startChunk(connection, chunk); } sendResponse(connection->server_sock, buf, ret); } } if (sock == connection->server_sock){ log_msg(log, "Received request from server\n"); memset(buf, 0, BUF_SIZE); ret = receive(sock, &master, &fdmax, browserListener, &buf, connection, stream); //Use close to avoid streamlining char *p, *type, *len, *hlen; char close[] = "close "; char contentType[] = "Content-Type: "; char header[100]; memset(header, '\0', 100); int x, contentLength; if (ret <= 0) { // printf("Continuing!\n"); continue; } if (strstr(buf, "Not Modified") != NULL){ exit(4); } if (memcmp(buf, "HTTP/1.1", strlen("HTTP/1.1")) == 0){ // printf("Is HTTP\n"); if ((p = strstr(buf, "Connection: ")) != NULL){ p = p + strlen("Connection: "); memcpy(p, close, strlen(close)); } // p is a pointer to Content-Type p = strstr(buf, contentType); if (p != NULL){ x = strcspn(p, "\n"); if (x > 99) x = 99; memcpy(header, p, x); header[x] = '\0'; fflush(stdout); if ((type = strstr(header, "Content-Type: ")) != NULL){ //found Content-Type type = type + strlen("Content-Type: "); } } // printf("TYPE:%s\n", type); if (ret > 0){ // printf("Received %d:\n%s\n",ret, buf); //If text/xml, set tput to be min if( strstr(type, "text/xml") != NULL){ stream->current_throughput = getBitrate(stream->current_throughput, stream->available_bitrates); } //measure header length until /n/r/n/r and then //subtract that from ret to see how much data you got and forward if ( strstr(type, "video/f4f") != NULL){ if ((len = strstr(buf, "Content-Length: ")) != NULL){ len = len + strlen("Content-Length: "); contentLength = atoi(len); connection->chunk_throughputs->chunk_size = contentLength; if ((hlen = strstr(buf, "\r\n\r\n")) != NULL){ hlen = hlen + strlen("\n\r\n\r"); unsigned int h = hlen - buf; unsigned int bytesRead = ret - h; // printf("bytesRead: %d\nbytesTotal: %d\n", bytesRead, contentLength); connection->chunk_throughputs->bytesLeft = contentLength - bytesRead; } } } sendResponse(connection->browser_sock, buf, ret); } } // end IF "HTTP/1.1" else{ // still reading same request chunk // printf("Reading video data\nBuf:\n%s\nRet: %d\n", buf, ret); // printf("Chunk throughputs: %p\n", connection->chunk_throughputs); if(connection->chunk_throughputs != NULL){ connection->chunk_throughputs->bytesLeft = connection->chunk_throughputs->bytesLeft - ret; if (connection->chunk_throughputs->bytesLeft == 0){ // printf("***FINISHING CHUNK***\n"); finishChunk(stream, connection, commandLine); // printf("BYE\n"); } } sendResponse(connection->browser_sock, buf, ret); } }//end server sock } // end ELSE } // end WHILE(1) close_socket(browserListener); //endLogger(); return EXIT_SUCCESS; }
void BrowseThread::populateModel() { m_path_mutex.lock(); MDir thisPath = m_path; BrowseTableModel* thisModelObserver = m_model_observer; m_path_mutex.unlock(); // Refresh the name filters in case we loaded new SoundSource plugins. QStringList nameFilters(SoundSourceProxy::getSupportedFileNamePatterns()); QDirIterator fileIt(thisPath.dir().absolutePath(), nameFilters, QDir::Files | QDir::NoDotAndDotDot); // remove all rows // This is a blocking operation // see signal/slot connection in BrowseTableModel emit(clearModel(thisModelObserver)); QList< QList<QStandardItem*> > rows; int row = 0; // Iterate over the files while (fileIt.hasNext()) { // If a user quickly jumps through the folders // the current task becomes "dirty" m_path_mutex.lock(); MDir newPath = m_path; m_path_mutex.unlock(); if (thisPath.dir() != newPath.dir()) { qDebug() << "Abort populateModel()"; return populateModel(); } QString filepath = fileIt.next(); auto pTrack = Track::newTemporary(filepath, thisPath.token()); SoundSourceProxy(pTrack).updateTrackFromSource(); QList<QStandardItem*> row_data; QStandardItem* item = new QStandardItem("0"); item->setData("0", Qt::UserRole); row_data.insert(COLUMN_PREVIEW, item); item = new QStandardItem(pTrack->getFileName()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_FILENAME, item); item = new QStandardItem(pTrack->getArtist()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ARTIST, item); item = new QStandardItem(pTrack->getTitle()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_TITLE, item); item = new QStandardItem(pTrack->getAlbum()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ALBUM, item); item = new QStandardItem(pTrack->getAlbumArtist()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_ALBUMARTIST, item); item = new QStandardItem(pTrack->getTrackNumber()); item->setToolTip(item->text()); item->setData(item->text().toInt(), Qt::UserRole); row_data.insert(COLUMN_TRACK_NUMBER, item); const QString year(pTrack->getYear()); item = new YearItem(year); item->setToolTip(year); // The year column is sorted according to the numeric calendar year item->setData(mixxx::TrackMetadata::parseCalendarYear(year), Qt::UserRole); row_data.insert(COLUMN_YEAR, item); item = new QStandardItem(pTrack->getGenre()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_GENRE, item); item = new QStandardItem(pTrack->getComposer()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_COMPOSER, item); item = new QStandardItem(pTrack->getGrouping()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_GROUPING, item); item = new QStandardItem(pTrack->getComment()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_COMMENT, item); QString duration = pTrack->getDurationText(mixxx::Duration::Precision::SECONDS); item = new QStandardItem(duration); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_DURATION, item); item = new QStandardItem(pTrack->getBpmText()); item->setToolTip(item->text()); item->setData(pTrack->getBpm(), Qt::UserRole); row_data.insert(COLUMN_BPM, item); item = new QStandardItem(pTrack->getKeyText()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_KEY, item); item = new QStandardItem(pTrack->getType()); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_TYPE, item); item = new QStandardItem(pTrack->getBitrateText()); item->setToolTip(item->text()); item->setData(pTrack->getBitrate(), Qt::UserRole); row_data.insert(COLUMN_BITRATE, item); QString location = pTrack->getLocation(); QString nativeLocation = QDir::toNativeSeparators(location); item = new QStandardItem(nativeLocation); item->setToolTip(nativeLocation); item->setData(location, Qt::UserRole); row_data.insert(COLUMN_NATIVELOCATION, item); QDateTime modifiedTime = pTrack->getFileModifiedTime().toLocalTime(); item = new QStandardItem(modifiedTime.toString(Qt::DefaultLocaleShortDate)); item->setToolTip(item->text()); item->setData(modifiedTime, Qt::UserRole); row_data.insert(COLUMN_FILE_MODIFIED_TIME, item); QDateTime creationTime = pTrack->getFileCreationTime().toLocalTime(); item = new QStandardItem(creationTime.toString(Qt::DefaultLocaleShortDate)); item->setToolTip(item->text()); item->setData(creationTime, Qt::UserRole); row_data.insert(COLUMN_FILE_CREATION_TIME, item); const mixxx::ReplayGain replayGain(pTrack->getReplayGain()); item = new QStandardItem( mixxx::ReplayGain::ratioToString(replayGain.getRatio())); item->setToolTip(item->text()); item->setData(item->text(), Qt::UserRole); row_data.insert(COLUMN_REPLAYGAIN, item); rows.append(row_data); ++row; // If 10 tracks have been analyzed, send it to GUI // Will limit GUI freezing if (row % 10 == 0) { // this is a blocking operation emit(rowsAppended(rows, thisModelObserver)); qDebug() << "Append " << rows.count() << " from " << filepath; rows.clear(); } // Sleep additionally for 10ms which prevents us from GUI freezes msleep(20); } emit(rowsAppended(rows, thisModelObserver)); qDebug() << "Append last " << rows.count(); }