001
014
015 package com.liferay.portlet.documentlibrary.util;
016
017 import com.liferay.portal.image.ImageToolImpl;
018 import com.liferay.portal.kernel.image.ImageTool;
019 import com.liferay.portal.kernel.log.Log;
020 import com.liferay.portal.kernel.log.LogFactoryUtil;
021 import com.liferay.portal.kernel.util.GetterUtil;
022
023 import com.xuggle.ferry.RefCounted;
024 import com.xuggle.xuggler.Global;
025 import com.xuggle.xuggler.IAudioResampler;
026 import com.xuggle.xuggler.IAudioSamples.Format;
027 import com.xuggle.xuggler.IAudioSamples;
028 import com.xuggle.xuggler.ICodec;
029 import com.xuggle.xuggler.IContainer;
030 import com.xuggle.xuggler.IContainerFormat;
031 import com.xuggle.xuggler.IPacket;
032 import com.xuggle.xuggler.IPixelFormat;
033 import com.xuggle.xuggler.IRational;
034 import com.xuggle.xuggler.IStream;
035 import com.xuggle.xuggler.IStreamCoder;
036 import com.xuggle.xuggler.IVideoPicture;
037 import com.xuggle.xuggler.IVideoResampler;
038 import com.xuggle.xuggler.video.ConverterFactory;
039 import com.xuggle.xuggler.video.IConverter;
040
041 import java.awt.image.BufferedImage;
042 import java.awt.image.RenderedImage;
043
044 import java.io.File;
045 import java.io.FileOutputStream;
046
047 import java.util.List;
048 import java.util.Properties;
049
050 import javax.imageio.ImageIO;
051
052
058 public abstract class LiferayConverter {
059
060 public abstract void convert() throws Exception;
061
062 protected void cleanUp(IPacket inputIPacket, IPacket outputIPacket) {
063 if (inputIPacket != null) {
064 inputIPacket.delete();
065 }
066
067 if (outputIPacket != null) {
068 outputIPacket.delete();
069 }
070 }
071
072 protected void cleanUp(
073 IStreamCoder[] inputIStreamCoders, IStreamCoder[] outputIStreamCoders) {
074
075 if (inputIStreamCoders != null) {
076 for (IStreamCoder iStreamCoder : inputIStreamCoders) {
077 if (iStreamCoder != null) {
078 iStreamCoder.close();
079 }
080 }
081 }
082
083 if (outputIStreamCoders != null) {
084 for (IStreamCoder iStreamCoder : outputIStreamCoders) {
085 if (iStreamCoder != null) {
086 iStreamCoder.close();
087 }
088 }
089 }
090 }
091
092 protected void cleanUp(
093 RefCounted[] inputRefCountedArray, RefCounted[] outputRefCountedArray) {
094
095 if (inputRefCountedArray != null) {
096 for (RefCounted refCounted : inputRefCountedArray) {
097 if (refCounted != null) {
098 refCounted.delete();
099 }
100 }
101 }
102
103 if (outputRefCountedArray != null) {
104 for (RefCounted refCounted : outputRefCountedArray) {
105 if (refCounted != null) {
106 refCounted.delete();
107 }
108 }
109 }
110 }
111
112 protected int countNonKeyAfterKey(
113 IPacket inputIPacket, Boolean keyPacketFound, int nonKeyAfterKeyCount) {
114
115 if (inputIPacket.isKey()) {
116 nonKeyAfterKeyCount = 0;
117 }
118 else if (keyPacketFound) {
119 nonKeyAfterKeyCount++;
120 }
121
122 return nonKeyAfterKeyCount;
123 }
124
125 protected IAudioResampler createIAudioResampler(
126 IStreamCoder inputIStreamCoder, IStreamCoder outputIStreamCoder)
127 throws Exception {
128
129 IAudioResampler iAudioResampler = null;
130
131 Format inputSampleFormat = inputIStreamCoder.getSampleFormat();
132 Format outputSampleFormat = outputIStreamCoder.getSampleFormat();
133
134 if ((inputIStreamCoder.getChannels() ==
135 outputIStreamCoder.getChannels()) &&
136 (inputIStreamCoder.getSampleRate() ==
137 outputIStreamCoder.getSampleRate()) &&
138 inputSampleFormat.equals(outputSampleFormat)) {
139
140 return iAudioResampler;
141 }
142
143 iAudioResampler = IAudioResampler.make(
144 outputIStreamCoder.getChannels(), inputIStreamCoder.getChannels(),
145 outputIStreamCoder.getSampleRate(),
146 inputIStreamCoder.getSampleRate(),
147 outputIStreamCoder.getSampleFormat(),
148 inputIStreamCoder.getSampleFormat());
149
150 if (iAudioResampler == null) {
151 throw new RuntimeException("Audio resampling is not supported");
152 }
153
154 return iAudioResampler;
155 }
156
157 protected IVideoResampler createIVideoResampler(
158 IStreamCoder inputIStreamCoder, IStreamCoder outputIStreamCoder,
159 int height, int width)
160 throws Exception {
161
162 IVideoResampler iVideoResampler = null;
163
164 IPixelFormat.Type inputIPixelFormatType =
165 inputIStreamCoder.getPixelType();
166 IPixelFormat.Type outputIPixelFormatType =
167 outputIStreamCoder.getPixelType();
168
169 if ((height == inputIStreamCoder.getHeight()) &&
170 (width == inputIStreamCoder.getWidth()) &&
171 inputIPixelFormatType.equals(outputIPixelFormatType)) {
172
173 return iVideoResampler;
174 }
175
176 iVideoResampler = IVideoResampler.make(
177 width, height, outputIStreamCoder.getPixelType(),
178 inputIStreamCoder.getWidth(), inputIStreamCoder.getHeight(),
179 inputIStreamCoder.getPixelType());
180
181 if (iVideoResampler == null) {
182 throw new RuntimeException("Video resampling is not supported");
183 }
184
185 return iVideoResampler;
186 }
187
188 protected void decodeAudio(
189 IAudioResampler iAudioResampler, IAudioSamples inputIAudioSample,
190 IAudioSamples resampledIAudioSample, IPacket inputIPacket,
191 IPacket outputIPacket, IStreamCoder inputIStreamCoder,
192 IStreamCoder outputIStreamCoder, IContainer outputIContainer,
193 int currentPacketSize, int previousPacketSize, int streamIndex,
194 long timeStampOffset)
195 throws Exception {
196
197 int offset = 0;
198
199 while (offset < inputIPacket.getSize()) {
200 boolean stopDecoding = false;
201
202 int value = inputIStreamCoder.decodeAudio(
203 inputIAudioSample, inputIPacket, offset);
204
205 if (value <= 0) {
206 if ((previousPacketSize == currentPacketSize) &&
207 (previousPacketSize != -1)) {
208
209 throw new RuntimeException(
210 "Unable to decode audio stream " + streamIndex);
211 }
212 else {
213 stopDecoding = true;
214 }
215 }
216
217 updateAudioTimeStamp(inputIAudioSample, timeStampOffset);
218
219 offset += value;
220
221 IAudioSamples outputIAudioSample = resampleAudio(
222 iAudioResampler, inputIAudioSample, resampledIAudioSample);
223
224 encodeAudio(
225 outputIStreamCoder, outputIPacket, outputIAudioSample,
226 outputIContainer);
227
228 if (stopDecoding) {
229 if (_log.isDebugEnabled()) {
230 _log.debug("Stop decoding audio stream " + streamIndex);
231 }
232
233 break;
234 }
235 }
236 }
237
238 protected int decodeVideo(
239 IVideoResampler iVideoResampler, IVideoPicture inputIVideoPicture,
240 IVideoPicture resampledIVideoPicture, IPacket inputIPacket,
241 IPacket outputIPacket, IStreamCoder inputIStreamCoder,
242 IStreamCoder outputIStreamCoder, IContainer outputIContainer,
243 File thumbnailFile, String thumbnailExtension, int thumbnailHeight,
244 int thumbnailWidth, long timeStampOffset)
245 throws Exception {
246
247 int offset = 0;
248
249 boolean stopDecoding = false;
250
251 while (offset < inputIPacket.getSize()) {
252 int value = inputIStreamCoder.decodeVideo(
253 inputIVideoPicture, inputIPacket, offset);
254
255 if (value <= 0) {
256 return value;
257 }
258
259 updateVideoTimeStamp(inputIVideoPicture, timeStampOffset);
260
261 offset += value;
262
263
264
265
266 ICodec.ID iCodecID = inputIStreamCoder.getCodecID();
267
268 if (iCodecID.equals(ICodec.ID.CODEC_ID_MJPEG)) {
269 stopDecoding = true;
270 }
271
272 if (!inputIVideoPicture.isComplete()) {
273 if (stopDecoding) {
274 return 1;
275 }
276 else {
277 continue;
278 }
279 }
280
281 if (thumbnailFile != null) {
282 BufferedImage bufferedImage = null;
283
284 if (_converterFactoryType == null) {
285 _converterFactoryType =
286 ConverterFactory.findRegisteredConverter(
287 ConverterFactory.XUGGLER_BGR_24);
288 }
289
290 if (_converterFactoryType == null) {
291 throw new UnsupportedOperationException(
292 "No converter found for " +
293 ConverterFactory.XUGGLER_BGR_24);
294 }
295
296 if (_videoIConverter == null) {
297 _videoIConverter = ConverterFactory.createConverter(
298 _converterFactoryType.getDescriptor(),
299 inputIVideoPicture);
300 }
301
302 bufferedImage = _videoIConverter.toImage(inputIVideoPicture);
303
304 thumbnailFile.createNewFile();
305
306 ImageTool imageTool = ImageToolImpl.getInstance();
307
308 RenderedImage renderedImage = imageTool.scale(
309 bufferedImage, thumbnailHeight, thumbnailWidth);
310
311 ImageIO.write(
312 renderedImage, thumbnailExtension,
313 new FileOutputStream(thumbnailFile));
314
315 return DECODE_VIDEO_THUMBNAIL;
316 }
317
318 if ((outputIStreamCoder != null) && (outputIContainer != null)) {
319 IVideoPicture outputIVideoPicture = resampleVideo(
320 iVideoResampler, inputIVideoPicture,
321 resampledIVideoPicture);
322
323 outputIVideoPicture.setQuality(0);
324
325 encodeVideo(
326 outputIStreamCoder, outputIVideoPicture, outputIPacket,
327 outputIContainer);
328 }
329
330 if (stopDecoding) {
331 break;
332 }
333 }
334
335 return 1;
336 }
337
338 protected void encodeAudio(
339 IStreamCoder outputIStreamCoder, IPacket outputIPacket,
340 IAudioSamples outputIAudioSample, IContainer outputIContainer)
341 throws Exception {
342
343 int consumedSamplesCount = 0;
344
345 while (consumedSamplesCount < outputIAudioSample.getNumSamples()) {
346 int value = outputIStreamCoder.encodeAudio(
347 outputIPacket, outputIAudioSample, consumedSamplesCount);
348
349 if (value <= 0) {
350 throw new RuntimeException("Unable to encode audio");
351 }
352
353 consumedSamplesCount += value;
354
355 if (outputIPacket.isComplete()) {
356 value = outputIContainer.writePacket(outputIPacket, true);
357
358 if (value < 0) {
359 throw new RuntimeException("Unable to write audio packet");
360 }
361 }
362 }
363 }
364
365 protected void encodeVideo(
366 IStreamCoder outputIStreamCoder, IVideoPicture outputIVideoPicture,
367 IPacket outputIPacket, IContainer outputIContainer)
368 throws Exception {
369
370 int value = outputIStreamCoder.encodeVideo(
371 outputIPacket, outputIVideoPicture, 0);
372
373 if (value < 0) {
374 throw new RuntimeException("Unable to encode video");
375 }
376
377 if (outputIPacket.isComplete()) {
378 value = outputIContainer.writePacket(outputIPacket, true);
379
380 if (value < 0) {
381 throw new RuntimeException("Unable to write video packet");
382 }
383 }
384 }
385
386 protected void flush(
387 IStreamCoder outputIStreamCoder, IContainer outputIContainer,
388 IPacket iPacket) {
389
390 if (outputIStreamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
391 outputIStreamCoder.encodeAudio(iPacket, null, 0);
392 }
393 else {
394 outputIStreamCoder.encodeVideo(iPacket, null, 0);
395 }
396
397 if (iPacket.isComplete()) {
398 outputIContainer.writePacket(iPacket, true);
399 }
400 }
401
402 protected void flush(
403 IStreamCoder[] outputIStreamCoders, IContainer outputIContainer) {
404
405 for (IStreamCoder outputIStreamCoder : outputIStreamCoders) {
406 if (outputIStreamCoder == null) {
407 continue;
408 }
409
410 IPacket iPacket = IPacket.make();
411
412 flush(outputIStreamCoder, outputIContainer, iPacket);
413
414 while (iPacket.isComplete()) {
415 flush(outputIStreamCoder, outputIContainer, iPacket);
416 }
417 }
418 }
419
420 protected int getAudioBitRate(ICodec outputICodec, int originalBitRate) {
421 if ((originalBitRate == 0) || (originalBitRate > AUDIO_BIT_RATE_MAX)) {
422 originalBitRate = AUDIO_BIT_RATE_DEFAULT;
423 }
424
425 ICodec.ID iCodecID = outputICodec.getID();
426
427 if (iCodecID.equals(ICodec.ID.CODEC_ID_VORBIS)) {
428 if (originalBitRate < 64000) {
429 originalBitRate = 64000;
430 }
431 }
432
433 return originalBitRate;
434 }
435
436 protected int getAudioEncodingChannels(
437 IContainer outputIContainer, int channels) {
438
439 IContainerFormat iContainerFormat =
440 outputIContainer.getContainerFormat();
441
442 String outputFormat = iContainerFormat.getOutputFormatShortName();
443
444 if (outputFormat.equals("ogg")) {
445 return 2;
446 }
447
448 if ((channels == 0) || (channels > 2)) {
449 channels = 2;
450 }
451
452 return channels;
453 }
454
455 protected ICodec getAudioEncodingICodec(IContainer outputIContainer) {
456 IContainerFormat iContainerFormat =
457 outputIContainer.getContainerFormat();
458
459 String outputFormat = iContainerFormat.getOutputFormatShortName();
460
461 if (outputFormat.equals("ogg")) {
462 return ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_VORBIS);
463 }
464
465 return null;
466 }
467
468 protected Format getAudioSampleFormat(
469 ICodec outputICodec, Format originalSampleFormat) {
470
471 Format sampleFormat = null;
472
473 List<Format> supportedSampleFormats =
474 outputICodec.getSupportedAudioSampleFormats();
475
476 for (Format supportedSampleFormat : supportedSampleFormats) {
477 sampleFormat = supportedSampleFormat;
478
479 if (supportedSampleFormat == originalSampleFormat) {
480 break;
481 }
482 }
483
484 return sampleFormat;
485 }
486
487 protected int getAudioSampleRate() {
488 return AUDIO_SAMPLE_RATE_DEFAULT;
489 }
490
491 protected abstract IContainer getInputIContainer();
492
493 protected int getProperty(
494 int originalValue, int defaultValue, int maxValue) {
495
496 if (originalValue <= 0) {
497 originalValue = defaultValue;
498 }
499 else if (originalValue > maxValue) {
500 originalValue = maxValue;
501 }
502
503 return originalValue;
504 }
505
506 protected int getProperty(
507 Properties properties, String propertyName, String prettyPropertyName,
508 String container, int defaultValue, int maxValue) {
509
510 int property = GetterUtil.getInteger(
511 properties.getProperty(propertyName + "[" + container + "]"),
512 defaultValue);
513
514 if (property > maxValue) {
515 property = maxValue;
516 }
517
518 if (_log.isInfoEnabled()) {
519 _log.info(
520 "Default " + prettyPropertyName + " for " + container +
521 " configured to " + property);
522 }
523
524 return property;
525 }
526
527 protected long getSeekTimeStamp(int percentage) throws Exception {
528 IContainer inputIContainer = getInputIContainer();
529
530 long seekTimeStamp = -1;
531
532 long videoSeconds = inputIContainer.getDuration() / 1000000L;
533
534 long seekSeconds = ((videoSeconds * percentage) / 100L);
535
536 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
537 IStream inputIStream = inputIContainer.getStream(i);
538
539 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
540
541 if (inputIStreamCoder.getCodecType() !=
542 ICodec.Type.CODEC_TYPE_VIDEO) {
543
544 continue;
545 }
546
547 IRational iRational = inputIStream.getTimeBase();
548
549 long timeStampOffset =
550 iRational.getDenominator() / iRational.getNumerator() *
551 seekSeconds;
552
553 seekTimeStamp = inputIContainer.getStartTime() + timeStampOffset;
554
555 break;
556 }
557
558 return seekTimeStamp;
559 }
560
561 protected long getStreamTimeStampOffset(IStream iStream) {
562 long timeStampOffset = 0;
563
564 if ((iStream.getStartTime() != Global.NO_PTS) &&
565 (iStream.getStartTime() > 0) && (iStream.getTimeBase() != null)) {
566
567 IRational iRational = IRational.make(
568 1, (int)Global.DEFAULT_PTS_PER_SECOND);
569
570 timeStampOffset = iRational.rescale(
571 iStream.getStartTime(), iStream.getTimeBase());
572 }
573
574 return timeStampOffset;
575 }
576
577 protected boolean isKeyPacketFound(
578 IPacket inputIPacket, boolean keyPacketFound) {
579
580 if (inputIPacket.isKey() && !keyPacketFound) {
581 return true;
582 }
583
584 return keyPacketFound;
585 }
586
587 protected boolean isStartDecoding(
588 IPacket inputIPacket, IStreamCoder inputIStreamCoder,
589 boolean keyPacketFound, int nonKeyAfterKeyCount,
590 boolean onlyDecodeKeyPackets) {
591
592 if (onlyDecodeKeyPackets && !inputIPacket.isKey()) {
593 return false;
594 }
595
596 ICodec.ID iCodecID = inputIStreamCoder.getCodecID();
597
598 if (iCodecID.equals(ICodec.ID.CODEC_ID_MJPEG)) {
599 return true;
600 }
601 else if (iCodecID.equals(ICodec.ID.CODEC_ID_MPEG2VIDEO) ||
602 iCodecID.equals(ICodec.ID.CODEC_ID_THEORA)) {
603
604 if (nonKeyAfterKeyCount != 1) {
605 return true;
606 }
607
608 return false;
609 }
610
611 return keyPacketFound;
612 }
613
614 protected void openContainer(
615 IContainer iContainer, String url, boolean writeContainer)
616 throws Exception {
617
618 int value = 0;
619
620 if (writeContainer) {
621 value = iContainer.open(url, IContainer.Type.WRITE, null);
622 }
623 else {
624 value = iContainer.open(url, IContainer.Type.READ, null);
625 }
626
627 if (value < 0) {
628 if (writeContainer) {
629 throw new RuntimeException("Unable to open output URL");
630 }
631 else {
632 throw new RuntimeException("Unable to open input URL");
633 }
634 }
635 }
636
637 protected void openStreamCoder(IStreamCoder iStreamCoder) throws Exception {
638 if ((iStreamCoder != null) &&
639 (iStreamCoder.getCodecType() != ICodec.Type.CODEC_TYPE_UNKNOWN)) {
640
641 int result = iStreamCoder.setStandardsCompliance(
642 IStreamCoder.CodecStandardsCompliance.COMPLIANCE_EXPERIMENTAL);
643
644 if (result < 0) {
645 throw new RuntimeException(
646 "Unable to set compliance mode to experimental");
647 }
648
649 if (iStreamCoder.open(null, null) < 0) {
650 throw new RuntimeException("Unable to open coder");
651 }
652 }
653 }
654
655 protected void prepareAudio(
656 IAudioResampler[] iAudioResamplers,
657 IAudioSamples[] inputIAudioSamples,
658 IAudioSamples[] outputIAudioSamples, IStreamCoder inputIStreamCoder,
659 IStreamCoder[] outputIStreamCoders, IContainer outputIContainer,
660 IStream[] outputIStreams, ICodec.Type inputICodecType,
661 String outputURL, int index)
662 throws Exception {
663
664 ICodec iCodec = getAudioEncodingICodec(outputIContainer);
665
666 if (iCodec == null) {
667 iCodec = ICodec.guessEncodingCodec(
668 null, null, outputURL, null, inputICodecType);
669 }
670
671 if (iCodec == null) {
672 throw new RuntimeException(
673 "Unable to determine " + inputICodecType + " encoder for " +
674 outputURL);
675 }
676
677 IStream outputIStream = outputIContainer.addNewStream(iCodec);
678
679 outputIStreams[index] = outputIStream;
680
681 IStreamCoder outputIStreamCoder = outputIStream.getStreamCoder();
682
683 outputIStreamCoders[index] = outputIStreamCoder;
684
685 int bitRate = inputIStreamCoder.getBitRate();
686
687 if (_log.isInfoEnabled()) {
688 _log.info("Original audio bitrate " + bitRate);
689 }
690
691 bitRate = getAudioBitRate(iCodec, bitRate);
692
693 if (_log.isInfoEnabled()) {
694 _log.info("Modified audio bitrate " + bitRate);
695 }
696
697 outputIStreamCoder.setBitRate(bitRate);
698
699 int channels = getAudioEncodingChannels(
700 outputIContainer, inputIStreamCoder.getChannels());
701
702 outputIStreamCoder.setChannels(channels);
703
704 outputIStreamCoder.setGlobalQuality(0);
705
706 Format sampleFormat = inputIStreamCoder.getSampleFormat();
707
708 if (_log.isInfoEnabled()) {
709 _log.info(
710 "Original audio sample format " + sampleFormat.toString());
711 }
712
713 sampleFormat = getAudioSampleFormat(iCodec, sampleFormat);
714
715 if (_log.isInfoEnabled()) {
716 _log.info(
717 "Modified audio sample format " + sampleFormat.toString());
718 }
719
720 outputIStreamCoder.setSampleFormat(sampleFormat);
721
722 outputIStreamCoder.setSampleRate(getAudioSampleRate());
723
724 iAudioResamplers[index] = createIAudioResampler(
725 inputIStreamCoder, outputIStreamCoder);
726
727 inputIAudioSamples[index] = IAudioSamples.make(
728 1024, inputIStreamCoder.getChannels(),
729 inputIStreamCoder.getSampleFormat());
730 outputIAudioSamples[index] = IAudioSamples.make(
731 1024, outputIStreamCoder.getChannels(),
732 outputIStreamCoder.getSampleFormat());
733 }
734
735 protected IAudioSamples resampleAudio(
736 IAudioResampler iAudioResampler, IAudioSamples inputIAudioSample,
737 IAudioSamples resampledIAudioSample)
738 throws Exception {
739
740 if ((iAudioResampler == null) ||
741 (inputIAudioSample.getNumSamples() <= 0)) {
742
743 return inputIAudioSample;
744 }
745
746 iAudioResampler.resample(
747 resampledIAudioSample, inputIAudioSample,
748 inputIAudioSample.getNumSamples());
749
750 return resampledIAudioSample;
751 }
752
753 protected IVideoPicture resampleVideo(
754 IVideoResampler iVideoResampler, IVideoPicture inputIVideoPicture,
755 IVideoPicture resampledIVideoPicture)
756 throws Exception {
757
758 if (iVideoResampler == null) {
759 return inputIVideoPicture;
760 }
761
762 if (iVideoResampler.resample(
763 resampledIVideoPicture, inputIVideoPicture) < 0) {
764
765 throw new RuntimeException("Unable to resample video");
766 }
767
768 return resampledIVideoPicture;
769 }
770
771 protected void rewind() throws Exception {
772 IContainer inputIContainer = getInputIContainer();
773
774 if (inputIContainer == null) {
775 return;
776 }
777
778 int value = 0;
779
780 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
781 IStream inputIStream = inputIContainer.getStream(i);
782
783 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
784
785 if (inputIStreamCoder.getCodecType() !=
786 ICodec.Type.CODEC_TYPE_VIDEO) {
787
788 continue;
789 }
790
791 value = rewind(i);
792
793 if (value < 0) {
794 throw new RuntimeException("Error while seeking file");
795 }
796
797 break;
798 }
799 }
800
801 protected int rewind(int index) throws Exception {
802 IContainer inputIContainer = getInputIContainer();
803
804 if (inputIContainer == null) {
805 return -1;
806 }
807
808 int value = inputIContainer.seekKeyFrame(index, -1, 0);
809
810 if (value < 0) {
811 throw new RuntimeException("Error while seeking file");
812 }
813
814 return value;
815 }
816
817 protected int seek(int index, long timeStamp) throws Exception {
818 IContainer inputIContainer = getInputIContainer();
819
820 if (inputIContainer == null) {
821 return -1;
822 }
823
824 int value = inputIContainer.seekKeyFrame(index, timeStamp, 0);
825
826 if (value < 0) {
827 throw new RuntimeException("Error while seeking file");
828 }
829
830 return value;
831 }
832
833 protected long seek(long timeStamp) throws Exception {
834 IContainer inputIContainer = getInputIContainer();
835
836 if (inputIContainer == null) {
837 return -1;
838 }
839
840 int value = 0;
841
842 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
843 IStream inputIStream = inputIContainer.getStream(i);
844
845 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
846
847 if (inputIStreamCoder.getCodecType() !=
848 ICodec.Type.CODEC_TYPE_VIDEO) {
849
850 continue;
851 }
852
853 value = seek(i, timeStamp);
854
855 if (value < 0) {
856 throw new RuntimeException("Error while seeking file");
857 }
858
859 break;
860 }
861
862 return value;
863 }
864
865 protected void updateAudioTimeStamp(
866 IAudioSamples inputAudioSample, long timeStampOffset) {
867
868 if (inputAudioSample.getTimeStamp() != Global.NO_PTS) {
869 inputAudioSample.setTimeStamp(
870 inputAudioSample.getTimeStamp() - timeStampOffset);
871 }
872 }
873
874 protected void updateVideoTimeStamp(
875 IVideoPicture inputIVideoPicture, long timeStampOffset) {
876
877 if (inputIVideoPicture.getTimeStamp() != Global.NO_PTS) {
878 inputIVideoPicture.setTimeStamp(
879 inputIVideoPicture.getTimeStamp() - timeStampOffset);
880 }
881 }
882
883 protected static final int AUDIO_BIT_RATE_DEFAULT = 64000;
884
885 protected static final int AUDIO_BIT_RATE_MAX = 500000;
886
887 protected static final int AUDIO_SAMPLE_RATE_DEFAULT = 44100;
888
889 protected static final int AUDIO_SAMPLE_RATE_MAX = 192000;
890
891 protected static final int DECODE_VIDEO_THUMBNAIL = 2;
892
893 private static Log _log = LogFactoryUtil.getLog(LiferayConverter.class);
894
895 private ConverterFactory.Type _converterFactoryType;
896 private IConverter _videoIConverter;
897
898 }