001    /**
002     * Copyright (c) 2000-2012 Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portlet.documentlibrary.util;
016    
017    import com.liferay.portal.image.ImageToolImpl;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    
021    import com.xuggle.ferry.RefCounted;
022    import com.xuggle.xuggler.Global;
023    import com.xuggle.xuggler.IAudioResampler;
024    import com.xuggle.xuggler.IAudioSamples.Format;
025    import com.xuggle.xuggler.IAudioSamples;
026    import com.xuggle.xuggler.ICodec;
027    import com.xuggle.xuggler.IContainer;
028    import com.xuggle.xuggler.IPacket;
029    import com.xuggle.xuggler.IPixelFormat;
030    import com.xuggle.xuggler.IRational;
031    import com.xuggle.xuggler.IStream;
032    import com.xuggle.xuggler.IStreamCoder;
033    import com.xuggle.xuggler.IVideoPicture;
034    import com.xuggle.xuggler.IVideoResampler;
035    import com.xuggle.xuggler.video.ConverterFactory;
036    import com.xuggle.xuggler.video.IConverter;
037    
038    import java.awt.image.BufferedImage;
039    import java.awt.image.RenderedImage;
040    
041    import java.io.File;
042    import java.io.FileOutputStream;
043    
044    import javax.imageio.ImageIO;
045    
046    /**
047     * @author Juan González
048     * @author Sergio González
049     * @author Brian Wing Shun Chan
050     * @author Alexander Chow
051     */
052    public abstract class LiferayConverter {
053    
054            public abstract void convert() throws Exception;
055    
056            protected void cleanUp(IPacket inputIPacket, IPacket outputIPacket) {
057                    if (inputIPacket != null) {
058                            inputIPacket.delete();
059                    }
060    
061                    if (outputIPacket != null) {
062                            outputIPacket.delete();
063                    }
064            }
065    
066            protected void cleanUp(
067                    IStreamCoder[] inputIStreamCoders, IStreamCoder[] outputIStreamCoders) {
068    
069                    if (inputIStreamCoders != null) {
070                            for (IStreamCoder iStreamCoder : inputIStreamCoders) {
071                                    if (iStreamCoder != null) {
072                                            iStreamCoder.close();
073                                    }
074                            }
075                    }
076    
077                    if (outputIStreamCoders != null) {
078                            for (IStreamCoder iStreamCoder : outputIStreamCoders) {
079                                    if (iStreamCoder != null) {
080                                            iStreamCoder.close();
081                                    }
082                            }
083                    }
084            }
085    
086            protected void cleanUp(
087                    RefCounted[] inputRefCountedArray, RefCounted[] outputRefCountedArray) {
088    
089                    if (inputRefCountedArray != null) {
090                            for (RefCounted refCounted : inputRefCountedArray) {
091                                    if (refCounted != null) {
092                                            refCounted.delete();
093                                    }
094                            }
095                    }
096    
097                    if (outputRefCountedArray != null) {
098                            for (RefCounted refCounted : outputRefCountedArray) {
099                                    if (refCounted != null) {
100                                            refCounted.delete();
101                                    }
102                            }
103                    }
104            }
105    
106            protected int countNonKeyAfterKey(
107                    IPacket inputIPacket, Boolean keyPacketFound, int nonKeyAfterKeyCount) {
108    
109                    if (inputIPacket.isKey()) {
110                            nonKeyAfterKeyCount = 0;
111                    }
112                    else if (keyPacketFound) {
113                            nonKeyAfterKeyCount++;
114                    }
115    
116                    return nonKeyAfterKeyCount;
117            }
118    
119            protected IAudioResampler createIAudioResampler(
120                            IStreamCoder inputIStreamCoder, IStreamCoder outputIStreamCoder)
121                    throws Exception {
122    
123                    IAudioResampler iAudioResampler = null;
124    
125                    Format inputSampleFormat = inputIStreamCoder.getSampleFormat();
126                    Format outputSampleFormat = outputIStreamCoder.getSampleFormat();
127    
128                    if ((inputIStreamCoder.getChannels() ==
129                                    outputIStreamCoder.getChannels()) &&
130                            (inputIStreamCoder.getSampleRate() ==
131                                    outputIStreamCoder.getSampleRate()) &&
132                            inputSampleFormat.equals(outputSampleFormat)) {
133    
134                            return iAudioResampler;
135                    }
136    
137                    iAudioResampler = IAudioResampler.make(
138                            outputIStreamCoder.getChannels(), inputIStreamCoder.getChannels(),
139                            outputIStreamCoder.getSampleRate(),
140                            inputIStreamCoder.getSampleRate(),
141                            outputIStreamCoder.getSampleFormat(),
142                            inputIStreamCoder.getSampleFormat());
143    
144                    if (iAudioResampler == null) {
145                            throw new RuntimeException("Audio resampling is not supported");
146                    }
147    
148                    return iAudioResampler;
149            }
150    
151            protected IVideoResampler createIVideoResampler(
152                            IStreamCoder inputIStreamCoder, IStreamCoder outputIStreamCoder,
153                            int height, int width)
154                    throws Exception {
155    
156                    IVideoResampler iVideoResampler = null;
157    
158                    IPixelFormat.Type inputIPixelFormatType =
159                            inputIStreamCoder.getPixelType();
160                    IPixelFormat.Type outputIPixelFormatType =
161                            outputIStreamCoder.getPixelType();
162    
163                    if ((height == inputIStreamCoder.getHeight()) &&
164                            (width == inputIStreamCoder.getWidth()) &&
165                            inputIPixelFormatType.equals(outputIPixelFormatType)) {
166    
167                            return iVideoResampler;
168                    }
169    
170                    iVideoResampler = IVideoResampler.make(
171                            width, height, outputIStreamCoder.getPixelType(),
172                            inputIStreamCoder.getWidth(), inputIStreamCoder.getHeight(),
173                            inputIStreamCoder.getPixelType());
174    
175                    if (iVideoResampler == null) {
176                            throw new RuntimeException("Video resampling is not supported");
177                    }
178    
179                    return iVideoResampler;
180            }
181    
182            protected void decodeAudio(
183                            IAudioResampler iAudioResampler, IAudioSamples inputIAudioSample,
184                            IAudioSamples resampledIAudioSample, IPacket inputIPacket,
185                            IPacket outputIPacket, IStreamCoder inputIStreamCoder,
186                            IStreamCoder outputIStreamCoder, IContainer outputIContainer,
187                            int currentPacketSize, int previousPacketSize, int streamIndex,
188                            long timeStampOffset)
189                    throws Exception {
190    
191                    int offset = 0;
192    
193                    while (offset < inputIPacket.getSize()) {
194                            boolean stopDecoding = false;
195    
196                            int value = inputIStreamCoder.decodeAudio(
197                                    inputIAudioSample, inputIPacket, offset);
198    
199                            if (value <= 0) {
200                                    if ((previousPacketSize == currentPacketSize) &&
201                                            (previousPacketSize != -1)) {
202    
203                                            throw new RuntimeException(
204                                                    "Unable to decode audio stream " + streamIndex);
205                                    }
206                                    else {
207                                            stopDecoding = true;
208                                    }
209                            }
210    
211                            updateAudioTimeStamp(inputIAudioSample, timeStampOffset);
212    
213                            offset += value;
214    
215                            IAudioSamples outputIAudioSample = resampleAudio(
216                                    iAudioResampler, inputIAudioSample, resampledIAudioSample);
217    
218                            encodeAudio(
219                                    outputIStreamCoder, outputIPacket, outputIAudioSample,
220                                    outputIContainer);
221    
222                            if (stopDecoding) {
223                                    if (_log.isDebugEnabled()) {
224                                            _log.debug("Stop decoding audio stream " + streamIndex);
225                                    }
226    
227                                    break;
228                            }
229                    }
230            }
231    
232            protected int decodeVideo(
233                            IVideoResampler iVideoResampler, IVideoPicture inputIVideoPicture,
234                            IVideoPicture resampledIVideoPicture, IPacket inputIPacket,
235                            IPacket outputIPacket, IStreamCoder inputIStreamCoder,
236                            IStreamCoder outputIStreamCoder, IContainer outputIContainer,
237                            File thumbnailFile, String thumbnailExtension, int thumbnailHeight,
238                            int thumbnailWidth, long timeStampOffset)
239                    throws Exception {
240    
241                    int offset = 0;
242    
243                    boolean stopDecoding = false;
244    
245                    while (offset < inputIPacket.getSize()) {
246                            int value = inputIStreamCoder.decodeVideo(
247                                    inputIVideoPicture, inputIPacket, offset);
248    
249                            if (value <= 0) {
250                                    return value;
251                            }
252    
253                            updateVideoTimeStamp(inputIVideoPicture, timeStampOffset);
254    
255                            offset += value;
256    
257                            // Workaround for FFmpeg bug. See
258                            // http://comments.gmane.org/gmane.comp.video.ffmpeg.devel/135657
259    
260                            ICodec.ID iCodecID = inputIStreamCoder.getCodecID();
261    
262                            if (iCodecID.equals(ICodec.ID.CODEC_ID_MJPEG)) {
263                                    stopDecoding = true;
264                            }
265    
266                            if (!inputIVideoPicture.isComplete()) {
267                                    if (stopDecoding) {
268                                            return 1;
269                                    }
270                                    else {
271                                            continue;
272                                    }
273                            }
274    
275                            if (thumbnailFile != null) {
276                                    BufferedImage bufferedImage = null;
277    
278                                    if (_converterFactoryType == null) {
279                                            _converterFactoryType =
280                                                    ConverterFactory.findRegisteredConverter(
281                                                            ConverterFactory.XUGGLER_BGR_24);
282                                    }
283    
284                                    if (_converterFactoryType == null) {
285                                            throw new UnsupportedOperationException(
286                                                    "No converter found for " +
287                                                            ConverterFactory.XUGGLER_BGR_24);
288                                    }
289    
290                                    if (_videoIConverter == null) {
291                                            _videoIConverter = ConverterFactory.createConverter(
292                                                    _converterFactoryType.getDescriptor(),
293                                                    inputIVideoPicture);
294                                    }
295    
296                                    bufferedImage = _videoIConverter.toImage(inputIVideoPicture);
297    
298                                    thumbnailFile.createNewFile();
299    
300                                    ImageToolImpl imageToolImpl = ImageToolImpl.getInstance();
301    
302                                    RenderedImage renderedImage = imageToolImpl.scale(
303                                            bufferedImage, thumbnailHeight, thumbnailWidth);
304    
305                                    ImageIO.write(
306                                            renderedImage, thumbnailExtension,
307                                            new FileOutputStream(thumbnailFile));
308    
309                                    return DECODE_VIDEO_THUMBNAIL;
310                            }
311    
312                            if ((outputIStreamCoder != null) && (outputIContainer != null)) {
313                                    IVideoPicture outputIVideoPicture = resampleVideo(
314                                            iVideoResampler, inputIVideoPicture,
315                                            resampledIVideoPicture);
316    
317                                    outputIVideoPicture.setQuality(0);
318    
319                                    encodeVideo(
320                                            outputIStreamCoder, outputIVideoPicture, outputIPacket,
321                                            outputIContainer);
322                            }
323    
324                            if (stopDecoding) {
325                                    break;
326                            }
327                    }
328    
329                    return 1;
330            }
331    
332            protected void encodeAudio(
333                            IStreamCoder outputIStreamCoder, IPacket outputIPacket,
334                            IAudioSamples outputIAudioSample, IContainer outputIContainer)
335                    throws Exception {
336    
337                    int consumedSamplesCount = 0;
338    
339                    while (consumedSamplesCount < outputIAudioSample.getNumSamples()) {
340                            int value = outputIStreamCoder.encodeAudio(
341                                    outputIPacket, outputIAudioSample, consumedSamplesCount);
342    
343                            if (value <= 0) {
344                                    throw new RuntimeException("Unable to encode audio");
345                            }
346    
347                            consumedSamplesCount += value;
348    
349                            if (outputIPacket.isComplete()) {
350                                    value = outputIContainer.writePacket(outputIPacket, true);
351    
352                                    if (value < 0) {
353                                            throw new RuntimeException("Unable to write audio packet");
354                                    }
355                            }
356                    }
357            }
358    
359            protected void encodeVideo(
360                            IStreamCoder outputIStreamCoder, IVideoPicture outputIVideoPicture,
361                            IPacket outputIPacket, IContainer outputIContainer)
362                    throws Exception {
363    
364                    int value = outputIStreamCoder.encodeVideo(
365                            outputIPacket, outputIVideoPicture, 0);
366    
367                    if (value < 0) {
368                            throw new RuntimeException("Unable to encode video");
369                    }
370    
371                    if (outputIPacket.isComplete()) {
372                            value = outputIContainer.writePacket(outputIPacket, true);
373    
374                            if (value < 0) {
375                                    throw new RuntimeException("Unable to write video packet");
376                            }
377                    }
378            }
379    
380            protected void flush(
381                    IStreamCoder[] outputIStreamCoders, IContainer outputIContainer) {
382    
383                    for (IStreamCoder outputIStreamCoder : outputIStreamCoders) {
384                            if (outputIStreamCoder == null) {
385                                    continue;
386                            }
387    
388                            IPacket iPacket = IPacket.make();
389    
390                            flush(outputIStreamCoder, outputIContainer, iPacket);
391    
392                            while (iPacket.isComplete()) {
393                                    flush(outputIStreamCoder, outputIContainer, iPacket);
394                            }
395                    }
396            }
397    
398            protected void flush(
399                    IStreamCoder outputIStreamCoder, IContainer outputIContainer,
400                    IPacket iPacket) {
401    
402                    if (outputIStreamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
403                            outputIStreamCoder.encodeAudio(iPacket, null, 0);
404                    }
405                    else {
406                            outputIStreamCoder.encodeVideo(iPacket, null, 0);
407                    }
408    
409                    if (iPacket.isComplete()) {
410                            outputIContainer.writePacket(iPacket, true);
411                    }
412            }
413    
414            protected int getAudioEncodingChannels(
415                    IContainer outputIContainer, int channels) {
416    
417                    if ((channels == 0) || (channels > 2)) {
418                            channels = 2;
419                    }
420    
421                    return channels;
422            }
423    
424            protected ICodec getAudioEncodingICodec(IContainer outputIContainer) {
425                    return null;
426            }
427    
428            protected abstract IContainer getInputIContainer();
429    
430            protected long getSeekTimeStamp(int percentage) throws Exception {
431                    IContainer inputIContainer = getInputIContainer();
432    
433                    long seekTimeStamp = -1;
434    
435                    long videoSeconds = inputIContainer.getDuration() / 1000000L;
436    
437                    long seekSeconds = ((videoSeconds * percentage) / 100L);
438    
439                    for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
440                            IStream inputIStream = inputIContainer.getStream(i);
441    
442                            IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
443    
444                            if (inputIStreamCoder.getCodecType() !=
445                                            ICodec.Type.CODEC_TYPE_VIDEO) {
446    
447                                    continue;
448                            }
449    
450                            IRational iRational = inputIStream.getTimeBase();
451    
452                            long timeStampOffset =
453                                    iRational.getDenominator() / iRational.getNumerator() *
454                                            seekSeconds;
455    
456                            seekTimeStamp = inputIContainer.getStartTime() + timeStampOffset;
457    
458                            break;
459                    }
460    
461                    return seekTimeStamp;
462            }
463    
464            protected long getStreamTimeStampOffset(IStream iStream) {
465                    long timeStampOffset = 0;
466    
467                    if ((iStream.getStartTime() != Global.NO_PTS) &&
468                            (iStream.getStartTime() > 0) && (iStream.getTimeBase() != null)) {
469    
470                            IRational iRational = IRational.make(
471                                    1, (int)Global.DEFAULT_PTS_PER_SECOND);
472    
473                            timeStampOffset = iRational.rescale(
474                                    iStream.getStartTime(), iStream.getTimeBase());
475                    }
476    
477                    return timeStampOffset;
478            }
479    
480            protected boolean isKeyPacketFound(
481                    IPacket inputIPacket, boolean keyPacketFound) {
482    
483                    if (inputIPacket.isKey() && !keyPacketFound) {
484                            return true;
485                    }
486    
487                    return keyPacketFound;
488            }
489    
490            protected boolean isStartDecoding(
491                    IPacket inputIPacket, IStreamCoder inputIStreamCoder,
492                    boolean keyPacketFound, int nonKeyAfterKeyCount,
493                    boolean onlyDecodeKeyPackets) {
494    
495                    if (onlyDecodeKeyPackets && !inputIPacket.isKey()) {
496                            return false;
497                    }
498    
499                    ICodec.ID iCodecID = inputIStreamCoder.getCodecID();
500    
501                    if (iCodecID.equals(ICodec.ID.CODEC_ID_MJPEG)) {
502                            return true;
503                    }
504                    else if (iCodecID.equals(ICodec.ID.CODEC_ID_MPEG2VIDEO) ||
505                                     iCodecID.equals(ICodec.ID.CODEC_ID_THEORA)) {
506    
507                            if (nonKeyAfterKeyCount != 1) {
508                                    return true;
509                            }
510    
511                            return false;
512                    }
513    
514                    return keyPacketFound;
515            }
516    
517            protected void openContainer(
518                            IContainer iContainer, String url, boolean writeContainer)
519                    throws Exception {
520    
521                    int value = 0;
522    
523                    if (writeContainer) {
524                            value = iContainer.open(url, IContainer.Type.WRITE, null);
525                    }
526                    else {
527                            value = iContainer.open(url, IContainer.Type.READ, null);
528                    }
529    
530                    if (value < 0) {
531                            if (writeContainer) {
532                                    throw new RuntimeException("Unable to open output URL");
533                            }
534                            else {
535                                    throw new RuntimeException("Unable to open input URL");
536                            }
537                    }
538            }
539    
540            protected void openStreamCoder(IStreamCoder iStreamCoder)
541                    throws Exception {
542    
543                    if ((iStreamCoder != null) &&
544                            (iStreamCoder.getCodecType() != ICodec.Type.CODEC_TYPE_UNKNOWN)) {
545    
546                            if (iStreamCoder.open() < 0) {
547                                    throw new RuntimeException("Unable to open coder");
548                            }
549                    }
550            }
551    
552            protected void prepareAudio(
553                            IAudioResampler[] iAudioResamplers,
554                            IAudioSamples[] inputIAudioSamples,
555                            IAudioSamples[] outputIAudioSamples, IStreamCoder inputIStreamCoder,
556                            IStreamCoder[] outputIStreamCoders, IContainer outputIContainer,
557                            IStream[] outputIStreams, ICodec.Type inputICodecType,
558                            String outputURL, int index)
559                    throws Exception {
560    
561                    IStream outputIStream = outputIContainer.addNewStream(index);
562    
563                    outputIStreams[index] = outputIStream;
564    
565                    IStreamCoder outputIStreamCoder = outputIStream.getStreamCoder();
566    
567                    outputIStreamCoders[index] = outputIStreamCoder;
568    
569                    int bitRate = inputIStreamCoder.getBitRate();
570    
571                    if (_log.isInfoEnabled()) {
572                            _log.info("Original audio bitrate " + bitRate);
573                    }
574    
575                    if (bitRate == 0) {
576                            bitRate = _AUDIO_BIT_RATE_DEFAULT;
577                    }
578    
579                    if (_log.isInfoEnabled()) {
580                            _log.info("Modified audio bitrate " + bitRate);
581                    }
582    
583                    outputIStreamCoder.setBitRate(bitRate);
584    
585                    int channels = getAudioEncodingChannels(
586                            outputIContainer, inputIStreamCoder.getChannels());
587    
588                    outputIStreamCoder.setChannels(channels);
589    
590                    ICodec iCodec = getAudioEncodingICodec(outputIContainer);
591    
592                    if (iCodec == null) {
593                            iCodec = ICodec.guessEncodingCodec(
594                                    null, null, outputURL, null, inputICodecType);
595                    }
596    
597                    if (iCodec == null) {
598                            throw new RuntimeException(
599                                    "Unable to determine " + inputICodecType + " encoder for " +
600                                            outputURL);
601                    }
602    
603                    outputIStreamCoder.setCodec(iCodec);
604    
605                    outputIStreamCoder.setGlobalQuality(0);
606    
607                    outputIStreamCoder.setSampleRate(_AUDIO_SAMPLE_RATE_DEFAULT);
608    
609                    iAudioResamplers[index] = createIAudioResampler(
610                            inputIStreamCoder, outputIStreamCoder);
611    
612                    inputIAudioSamples[index] = IAudioSamples.make(
613                            1024, inputIStreamCoder.getChannels());
614                    outputIAudioSamples[index] = IAudioSamples.make(
615                            1024, outputIStreamCoder.getChannels());
616            }
617    
618            protected IAudioSamples resampleAudio(
619                            IAudioResampler iAudioResampler, IAudioSamples inputIAudioSample,
620                            IAudioSamples resampledIAudioSample)
621                    throws Exception {
622    
623                    if ((iAudioResampler == null) ||
624                            (inputIAudioSample.getNumSamples() <= 0)) {
625    
626                            return inputIAudioSample;
627                    }
628    
629                    iAudioResampler.resample(
630                            resampledIAudioSample, inputIAudioSample,
631                            inputIAudioSample.getNumSamples());
632    
633                    return resampledIAudioSample;
634            }
635    
636            protected IVideoPicture resampleVideo(
637                            IVideoResampler iVideoResampler, IVideoPicture inputIVideoPicture,
638                            IVideoPicture resampledIVideoPicture)
639                    throws Exception {
640    
641                    if (iVideoResampler == null) {
642                            return inputIVideoPicture;
643                    }
644    
645                    if (iVideoResampler.resample(
646                                    resampledIVideoPicture, inputIVideoPicture) < 0) {
647    
648                            throw new RuntimeException("Unable to resample video");
649                    }
650    
651                    return resampledIVideoPicture;
652            }
653    
654            protected void rewind() throws Exception {
655                    IContainer inputIContainer = getInputIContainer();
656    
657                    if (inputIContainer == null) {
658                            return;
659                    }
660    
661                    int value = 0;
662    
663                    for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
664                            IStream inputIStream = inputIContainer.getStream(i);
665    
666                            IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
667    
668                            if (inputIStreamCoder.getCodecType() !=
669                                            ICodec.Type.CODEC_TYPE_VIDEO) {
670    
671                                    continue;
672                            }
673    
674                            value = rewind(i);
675    
676                            if (value < 0) {
677                                    throw new RuntimeException("Error while seeking file");
678                            }
679    
680                            break;
681                    }
682            }
683    
684            protected int rewind(int index) throws Exception {
685                    IContainer inputIContainer = getInputIContainer();
686    
687                    if (inputIContainer == null) {
688                            return -1;
689                    }
690    
691                    int value = inputIContainer.seekKeyFrame(index, -1, 0);
692    
693                    if (value < 0) {
694                            throw new RuntimeException("Error while seeking file");
695                    }
696    
697                    return value;
698            }
699    
700            protected int seek(int index, long timeStamp) throws Exception {
701                    IContainer inputIContainer = getInputIContainer();
702    
703                    if (inputIContainer == null) {
704                            return -1;
705                    }
706    
707                    int value = inputIContainer.seekKeyFrame(index, timeStamp, 0);
708    
709                    if (value < 0) {
710                            throw new RuntimeException("Error while seeking file");
711                    }
712    
713                    return value;
714            }
715    
716            protected long seek(long timeStamp) throws Exception {
717                    IContainer inputIContainer = getInputIContainer();
718    
719                    if (inputIContainer == null) {
720                            return -1;
721                    }
722    
723                    int value = 0;
724    
725                    for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
726                            IStream inputIStream = inputIContainer.getStream(i);
727    
728                            IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
729    
730                            if (inputIStreamCoder.getCodecType() !=
731                                            ICodec.Type.CODEC_TYPE_VIDEO) {
732    
733                                    continue;
734                            }
735    
736                            value = seek(i, timeStamp);
737    
738                            if (value < 0) {
739                                    throw new RuntimeException("Error while seeking file");
740                            }
741    
742                            break;
743                    }
744    
745                    return value;
746            }
747    
748            protected void updateAudioTimeStamp(
749                    IAudioSamples inputAudioSample, long timeStampOffset) {
750    
751                    if (inputAudioSample.getTimeStamp() != Global.NO_PTS) {
752                            inputAudioSample.setTimeStamp(
753                                    inputAudioSample.getTimeStamp() - timeStampOffset);
754                    }
755            }
756    
757            protected void updateVideoTimeStamp(
758                    IVideoPicture inputIVideoPicture, long timeStampOffset) {
759    
760                    if (inputIVideoPicture.getTimeStamp() != Global.NO_PTS) {
761                            inputIVideoPicture.setTimeStamp(
762                                    inputIVideoPicture.getTimeStamp() - timeStampOffset);
763                    }
764            }
765    
766            protected static final int DECODE_VIDEO_THUMBNAIL = 2;
767    
768            private static final int _AUDIO_BIT_RATE_DEFAULT = 64000;
769    
770            private static final int _AUDIO_SAMPLE_RATE_DEFAULT = 44100;
771    
772            private static Log _log = LogFactoryUtil.getLog(LiferayConverter.class);
773    
774            private ConverterFactory.Type _converterFactoryType;
775            private IConverter _videoIConverter;
776    
777    }