Ticket #2496: videoPerformance_natives.patch

File videoPerformance_natives.patch, 11.1 KB (added by boyanl, 15 years ago)
  • src/audio_output/audio_output.cpp

    ### Eclipse Workspace Patch 1.0
    #P sophie2-native
     
    4848 
    4949        int* out = (int *) output; 
    5050 
    51  
    5251        //Calculate the position that portaudio will start playing our samples from. 
    5352        if (!called) { 
    5453                firstTime = timeInfo->currentTime; 
     
    5857        //int64 pos = playPos; 
    5958 
    6059 
    61         for (int i = 0; i < (int)frameCount; ++i) { 
    62                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     60        //Use Duff's device for less branching 
     61 
     62        int count = frameCount, n = (count + 7)/8; 
     63 
     64        switch(count%8) { 
     65        case 0: do {    *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     66        case 7:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     67        case 6:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     68        case 5:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     69        case 4:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     70        case 3:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     71        case 2:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     72        case 1:                 *out++ = BUFFER[playPos++ % BUFFER_SIZE]; 
     73        }while (--n > 0); 
    6374        } 
     75 
    6476        //playPos = pos; 
    6577 
    6678        return paContinue; 
     
    8799        vector<byte> chunk; 
    88100        SendChunkCommand(vector<byte> const& data, int& pos) : 
    89101                        Command(data, pos) { 
    90                 chunk = Message::readBinData(data, pos); 
     102                Message::readBinData(data, pos, chunk); 
    91103                assert((int)chunk.size() == CHUNK_BYTES); 
    92104                assert(getId() == SEND_CHUNK_ID); 
    93105                assert(pos == (int)data.size()); 
     
    137149                if (device == -1)       { 
    138150                        device = 0; 
    139151                } 
    140                 DUMP(device); 
    141                 TRACE; 
     152                //DUMP(device); 
     153                //TRACE; 
    142154                PaDeviceInfo const& info = *Pa_GetDeviceInfo(device); 
    143155                assert(&info != NULL); 
    144                 DUMP(info.name); 
     156                //DUMP(info.name); 
    145157                params.device = device; 
    146158                params.channelCount = NUM_CHANNELS; 
    147159                params.sampleFormat = SAMPLE_FORMAT; 
    148160                params.suggestedLatency = 0.2; //info.defaultHighOutputLatency; 
    149161                params.hostApiSpecificStreamInfo = NULL; 
    150162 
    151                 TRACE; 
     163                //TRACE; 
    152164                PaError err = Pa_OpenStream(&stream, NULL, &params, SAMPLE_RATE, 0, paClipOff, 
    153165                                portaudioCallback, NULL); 
    154166                verifyPa(err); 
     
    156168                //start_position = Pa_GetStreamTime(stream); 
    157169                verifyPa(Pa_StartStream(stream)); 
    158170 
    159                 cerr << "AudioOutputBridge::doStart() end" << endl; 
     171                //cerr << "AudioOutputBridge::doStart() end" << endl; 
    160172                return Response::createOk(); 
    161173 
    162174        } 
     
    205217                cerr << "got chunk: " << count++ << endl; 
    206218        } 
    207219        int* c = (int*)&chunk[0]; 
    208         for(int i = 0; i < CHUNK_SAMPLES; ++i) { 
    209                 BUFFER[writePos++ % BUFFER_SIZE] = c[i]; 
     220 
     221        //Use Duff's device for less branching 
     222 
     223        int cnt = CHUNK_SAMPLES, n = (cnt + 7)/8; 
     224        int i = 0; 
     225        switch(cnt%8) { 
     226        case 0: do {    BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     227        case 7:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     228        case 6:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     229        case 5:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     230        case 4:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     231        case 3:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     232        case 2:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     233        case 1:                 BUFFER[writePos++ % BUFFER_SIZE] = c[i++]; 
     234        }while (--n > 0); 
    210235        } 
     236 
    211237        return Response::createOk(); 
    212238} 
    213239 
  • src/media_decoder/Makefile

     
    1212 
    1313$(TARGET_MD): media_decoder.cpp media_decoder.h ../commons/*.h ../commons/*.cpp $(FF_PATH) 
    1414        mkdir -p $(MAIN_TARGET_ROOT)  
    15         g++ -static -Wall media_decoder.cpp $(FF_OBJ) ../commons/*.cpp -lz -lm -I $(FF_PATH) -o $@ -Os  
     15        g++ -static -Wall media_decoder.cpp $(FF_OBJ) ../commons/*.cpp -lz -lm -I $(FF_PATH) -o $@ -O3  
    1616        strip $(TARGET_MD); 
    1717        echo Done $(TARGET_MD) 
    1818 
  • src/commons/java_messages.h

     
    2121       #include <fcntl.h> 
    2222#endif 
    2323 
     24#include <cstring> 
    2425#include "util.h" 
    2526 
    2627enum CommandIds { 
     
    5960 
    6061        static int readInt(vector<byte> const& data, int& pos) { 
    6162                int res = 0; 
    62                 res |= data.at(pos++) << 0; 
    63                 res |= data.at(pos++) << 8; 
    64                 res |= data.at(pos++) << 16; 
    65                 res |= data.at(pos++) << 24; 
     63                res |= data[pos++] << 0; 
     64                res |= data[pos++] << 8; 
     65                res |= data[pos++] << 16; 
     66                res |= data[pos++] << 24; 
    6667                return res; 
    6768        } 
    6869 
    69         static vector<byte> readBinData(vector<byte> const& data, int& pos) { 
    70                 vector<byte> res; 
     70        /* 
     71         * Passing the 3rd argument (result) by reference to avoid returning the vector and copying 
     72         * res must be empty 
     73         */ 
     74        static void readBinData(vector<byte> const& data, int& pos, vector<byte>& res) { 
    7175                int len = readInt(data, pos); 
    72                 for (int i = 0; i < len; ++i) { 
    73                         res.push_back(data.at(pos++)); 
    74                 } 
    75                 return res; 
     76                res.resize (len); 
     77                memcpy (&res[0], &data[pos], len); 
     78                pos += len; 
    7679        } 
    7780 
    7881        //TODO currently will work only for ascii 
     
    9598        } 
    9699 
    97100        //the third argument is added, because otherwise this was not consistent with readBinData 
    98         static void writeBinData(vector<byte>& data, vector<byte> source, bool withSize = true) { 
     101        static void writeBinData(vector<byte>& data, const vector<byte>& source, bool withSize = true) { 
    99102                if(withSize) { 
    100103                        writeInt(data, (int)source.size()); 
    101104                } 
    102                 for (int i = 0; i < (int) source.size(); i++) { 
    103                         data.push_back(source.at(i)); 
    104                 } 
     105                int sz = data.size (); 
     106                data.resize (sz + source.size()); 
     107                memcpy (&data[sz], &source[0], source.size()); 
    105108        } 
    106109 
    107110        static void writeStringUtf8(vector<byte>& data, string const& value) { 
     
    193196 
    194197        void sendResponse(Response const& response) { 
    195198                int size = response.data.size(); 
    196                 cout.write((char*) &size, sizeof(int)); 
    197                 cout.write((char*) &response.data[0], response.data.size()); 
    198                 cout.flush(); 
     199                fwrite(&size, sizeof(int), 1, stdout); 
     200                fwrite(&response.data[0], 1, response.data.size(), stdout); 
     201                fflush(stdout); 
    199202        } 
    200203 
    201204        //the caller is responsible to delete the returned command! 
     
    208211                //fprintf(stderr, "readCommand(): size = %d\n", size); fflush(stderr); 
    209212                vector<byte> data(size); 
    210213 
    211                 //TODO why this one is not also fread? 
    212                 cin.read((char*) &(data[0]), size); 
     214                rc = fread(&data[0], 1, size, stdin); 
    213215                int pos = 0; 
    214216                int id = Message::readInt(data, pos); 
    215                 //fprintf(stderr, "readCommand(): command_id = %d\n", id); fflush(stderr); 
    216217                pos = 0; //reset pos             
    217218                //fprintf(stderr, "readCommand(): end reading command\n"); fflush(stderr); 
    218219                return createCommand(id, data, pos); 
  • src/media_decoder/media_decoder.cpp

     
    7474 
    7575static int64_t sophie_media_seek(URLContext *h, int64_t pos, int whence) { 
    7676        Sophie2MediaContext *s = (Sophie2MediaContext *) h->priv_data; 
    77         if (whence == SEEK_SET) { 
    78                 s->pos = pos; 
    79         } else if (whence == SEEK_CUR) { 
    80                 s->pos += pos; 
    81         } else if (whence == SEEK_END) { 
    82                 s->pos = DECODER.fileSize + pos; 
    83         } else if (whence == AVSEEK_SIZE) { 
    84                 return DECODER.fileSize; 
    85         } else { 
    86                 assert(false); 
     77 
     78        switch(whence) { 
     79                case SEEK_SET: 
     80                        s->pos = pos; 
     81                        break; 
     82                case SEEK_CUR: 
     83                        s->pos += pos; 
     84                        break; 
     85                case SEEK_END: 
     86                        s->pos = DECODER.fileSize + pos; 
     87                        break; 
     88                case AVSEEK_SIZE: 
     89                        return DECODER.fileSize; 
     90                default: 
     91                        assert(false); 
    8792        } 
    8893 
    8994        return s->pos; 
  • lib-src/Makefile

     
    6666 
    6767ffmpeg : $(TARGET_FF)  
    6868 
    69 FF_AR = ffmpeg-export-snapshot.tar.bz2 
    70 FF_EX = ffmpeg-export-2009-09-04 
     69FF_AR = ffmpeg-0.6.tar.bz2 
     70FF_EX = ffmpeg-0.6 
    7171 
    7272 
    7373$(JUNK_FF) : $(FF_AR) 
  • src/media_decoder/media_decoder.h

     
    214214                if (avcodec_open(pVideoCodecCtx, pVideoCodec) < 0) { 
    215215                        throw runtime_error("Decoder::initVideo - Cannot open codec!"); 
    216216                } 
     217 
     218                int w = pVideoCodecCtx->width; 
     219                int h = pVideoCodecCtx->height; 
     220 
     221                img_convert_ctx = sws_getContext(w, h, pVideoCodecCtx->pix_fmt, w, 
     222                                h, pixFMT, SWS_BICUBIC, NULL, NULL, NULL); 
     223 
     224                if (img_convert_ctx == NULL) { 
     225                        throw runtime_error( 
     226                                        "Decoder::decodeFrame - Cannot initialize the conversion context!"); 
     227                } 
     228 
    217229        } 
    218230        void initAudio() { 
    219231                pAudioCodecCtx = pFormatContext->streams[audioStream]->codec; 
     
    228240                return pFrame->linesize[0]; 
    229241        } 
    230242        int decodeFrame(vector<byte>& data) { 
    231                 struct SwsContext* img_convert_ctx = 0; 
    232243 
    233                 if (img_convert_ctx == NULL) { 
    234                         int w = pVideoCodecCtx->width; 
    235                         int h = pVideoCodecCtx->height; 
     244                //if (img_convert_ctx == NULL) { 
    236245 
    237                         img_convert_ctx = sws_getContext(w, h, pVideoCodecCtx->pix_fmt, w, 
    238                                         h, pixFMT, SWS_BICUBIC, NULL, NULL, NULL); 
    239  
    240                         if (img_convert_ctx == NULL) { 
    241                                 throw runtime_error( 
    242                                                 "Decoder::decodeFrame - Cannot initialize the conversion context!"); 
    243                         } 
    244  
    245                         sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, 
    246                                         pVideoCodecCtx->height, pFrameRGB->data, 
    247                                         pFrameRGB->linesize); 
    248                 } 
     246                sws_scale(img_convert_ctx, pFrame->data, pFrame->linesize, 0, 
     247                                pVideoCodecCtx->height, pFrameRGB->data, 
     248                                pFrameRGB->linesize); 
     249                //} 
    249250                return saveFrame(data, pFrameRGB, pVideoCodecCtx->width, 
    250251                                pVideoCodecCtx->height); 
    251252 
     
    290291//                              } 
    291292                                if (pktMillis >= millis) { 
    292293                                        if (frameFinished) { 
    293                                                 DUMP(packetCnt); 
     294                                                //DUMP(packetCnt); 
    294295                                                int res = decodeFrame(data); 
    295296                                                lastVideoMillis = millis; 
    296297                                                lastVideoDur = pktDur; 
     
    366367        AVFrame *pFrame, *pFrameRGB; 
    367368        AVCodec *pVideoCodec; 
    368369        PixelFormat pixFMT; 
     370        struct SwsContext* img_convert_ctx; 
    369371 
    370372        AVCodecContext *pAudioCodecCtx; 
    371373        AVCodec *pAudioCodec; 
     
    374376        int saveFrame(vector<byte>& data, AVFrame *pFrame, int width, int height) { 
    375377                int linesize = pFrame->linesize[0]; 
    376378                const int size = linesize * height; 
    377                 for (int i = 0; i < size; i++) 
    378                         data.push_back(pFrame->data[0][i]); 
     379                data.resize (size); 
     380 
     381                /*for (int i = 0; i < size; i++) 
     382                        data.push_back(pFrame->data[0][i]);*/ 
     383 
     384                memcpy (&data[0], pFrame->data[0], size); 
    379385                return size; 
    380386        } 
    381387 
     
    463469        SendBytesCommand(vector<byte> const& data, int& pos) : 
    464470                Command(data, pos) { 
    465471                filePos = readInt(data, pos); 
    466                 fileData = readBinData(data, pos); 
     472                readBinData(data, pos, fileData); 
    467473                assert(pos == (int) data.size()); 
    468474                assert(getId() == SEND_BYTES_COMMAND); 
    469475        } 
  • src/audio_output/Makefile

     
    2525$(TARGET_AO): audio_output.cpp ../commons/*.h ../commons/*.cpp $(TARGET_PO) 
    2626        @echo $@ invoked... 
    2727        mkdir -p $(MAIN_TARGET_ROOT) 
    28         g++ -static -Wall audio_output.cpp $(TARGET_PO)/libportaudio.a ../commons/*.cpp $(EXTRA_OPTIONS) -I $(TARGET_PO) -o $@ 
     28        g++ -static -Wall audio_output.cpp $(TARGET_PO)/libportaudio.a ../commons/*.cpp $(EXTRA_OPTIONS) -I $(TARGET_PO) -o $@ -O3 
    2929        @echo Compiled. 
    3030 
    3131clean: