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;
027 import com.xuggle.xuggler.IAudioSamples.Format;
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
277 continue;
278 }
279
280 if (thumbnailFile != null) {
281 BufferedImage bufferedImage = null;
282
283 if (_converterFactoryType == null) {
284 _converterFactoryType =
285 ConverterFactory.findRegisteredConverter(
286 ConverterFactory.XUGGLER_BGR_24);
287 }
288
289 if (_converterFactoryType == null) {
290 throw new UnsupportedOperationException(
291 "No converter found for " +
292 ConverterFactory.XUGGLER_BGR_24);
293 }
294
295 if (_videoIConverter == null) {
296 _videoIConverter = ConverterFactory.createConverter(
297 _converterFactoryType.getDescriptor(),
298 inputIVideoPicture);
299 }
300
301 bufferedImage = _videoIConverter.toImage(inputIVideoPicture);
302
303 thumbnailFile.createNewFile();
304
305 ImageTool imageTool = ImageToolImpl.getInstance();
306
307 RenderedImage renderedImage = imageTool.scale(
308 bufferedImage, thumbnailHeight, thumbnailWidth);
309
310 ImageIO.write(
311 renderedImage, thumbnailExtension,
312 new FileOutputStream(thumbnailFile));
313
314 return DECODE_VIDEO_THUMBNAIL;
315 }
316
317 if ((outputIStreamCoder != null) && (outputIContainer != null)) {
318 IVideoPicture outputIVideoPicture = resampleVideo(
319 iVideoResampler, inputIVideoPicture,
320 resampledIVideoPicture);
321
322 outputIVideoPicture.setQuality(0);
323
324 encodeVideo(
325 outputIStreamCoder, outputIVideoPicture, outputIPacket,
326 outputIContainer);
327 }
328
329 if (stopDecoding) {
330 break;
331 }
332 }
333
334 return 1;
335 }
336
337 protected void encodeAudio(
338 IStreamCoder outputIStreamCoder, IPacket outputIPacket,
339 IAudioSamples outputIAudioSample, IContainer outputIContainer)
340 throws Exception {
341
342 int consumedSamplesCount = 0;
343
344 while (consumedSamplesCount < outputIAudioSample.getNumSamples()) {
345 int value = outputIStreamCoder.encodeAudio(
346 outputIPacket, outputIAudioSample, consumedSamplesCount);
347
348 if (value <= 0) {
349 throw new RuntimeException("Unable to encode audio");
350 }
351
352 consumedSamplesCount += value;
353
354 if (outputIPacket.isComplete()) {
355 value = outputIContainer.writePacket(outputIPacket, true);
356
357 if (value < 0) {
358 throw new RuntimeException("Unable to write audio packet");
359 }
360 }
361 }
362 }
363
364 protected void encodeVideo(
365 IStreamCoder outputIStreamCoder, IVideoPicture outputIVideoPicture,
366 IPacket outputIPacket, IContainer outputIContainer)
367 throws Exception {
368
369 int value = outputIStreamCoder.encodeVideo(
370 outputIPacket, outputIVideoPicture, 0);
371
372 if (value < 0) {
373 throw new RuntimeException("Unable to encode video");
374 }
375
376 if (outputIPacket.isComplete()) {
377 value = outputIContainer.writePacket(outputIPacket, true);
378
379 if (value < 0) {
380 throw new RuntimeException("Unable to write video packet");
381 }
382 }
383 }
384
385 protected void flush(
386 IStreamCoder outputIStreamCoder, IContainer outputIContainer,
387 IPacket iPacket) {
388
389 if (outputIStreamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
390 outputIStreamCoder.encodeAudio(iPacket, null, 0);
391 }
392 else {
393 outputIStreamCoder.encodeVideo(iPacket, null, 0);
394 }
395
396 if (iPacket.isComplete()) {
397 outputIContainer.writePacket(iPacket, true);
398 }
399 }
400
401 protected void flush(
402 IStreamCoder[] outputIStreamCoders, IContainer outputIContainer) {
403
404 for (IStreamCoder outputIStreamCoder : outputIStreamCoders) {
405 if (outputIStreamCoder == null) {
406 continue;
407 }
408
409 IPacket iPacket = IPacket.make();
410
411 flush(outputIStreamCoder, outputIContainer, iPacket);
412
413 while (iPacket.isComplete()) {
414 flush(outputIStreamCoder, outputIContainer, iPacket);
415 }
416 }
417 }
418
419 protected int getAudioBitRate(ICodec outputICodec, int originalBitRate) {
420 if ((originalBitRate == 0) || (originalBitRate > AUDIO_BIT_RATE_MAX)) {
421 originalBitRate = AUDIO_BIT_RATE_DEFAULT;
422 }
423
424 ICodec.ID iCodecID = outputICodec.getID();
425
426 if (iCodecID.equals(ICodec.ID.CODEC_ID_VORBIS)) {
427 if (originalBitRate < 64000) {
428 originalBitRate = 64000;
429 }
430 }
431
432 return originalBitRate;
433 }
434
435 protected int getAudioEncodingChannels(
436 IContainer outputIContainer, int channels) {
437
438 IContainerFormat iContainerFormat =
439 outputIContainer.getContainerFormat();
440
441 String outputFormat = iContainerFormat.getOutputFormatShortName();
442
443 if (outputFormat.equals("ogg")) {
444 return 2;
445 }
446
447 if ((channels == 0) || (channels > 2)) {
448 channels = 2;
449 }
450
451 return channels;
452 }
453
454 protected ICodec getAudioEncodingICodec(IContainer outputIContainer) {
455 IContainerFormat iContainerFormat =
456 outputIContainer.getContainerFormat();
457
458 String outputFormat = iContainerFormat.getOutputFormatShortName();
459
460 if (outputFormat.equals("ogg")) {
461 return ICodec.findEncodingCodec(ICodec.ID.CODEC_ID_VORBIS);
462 }
463
464 return null;
465 }
466
467 protected Format getAudioSampleFormat(
468 ICodec outputICodec, Format originalSampleFormat) {
469
470 Format sampleFormat = null;
471
472 List<Format> supportedSampleFormats =
473 outputICodec.getSupportedAudioSampleFormats();
474
475 for (Format supportedSampleFormat : supportedSampleFormats) {
476 sampleFormat = supportedSampleFormat;
477
478 if (supportedSampleFormat == originalSampleFormat) {
479 break;
480 }
481 }
482
483 return sampleFormat;
484 }
485
486 protected int getAudioSampleRate() {
487 return AUDIO_SAMPLE_RATE_DEFAULT;
488 }
489
490 protected abstract IContainer getInputIContainer();
491
492 protected int getProperty(
493 int originalValue, int defaultValue, int maxValue) {
494
495 if (originalValue <= 0) {
496 originalValue = defaultValue;
497 }
498 else if (originalValue > maxValue) {
499 originalValue = maxValue;
500 }
501
502 return originalValue;
503 }
504
505 protected int getProperty(
506 Properties properties, String propertyName, String prettyPropertyName,
507 String container, int defaultValue, int maxValue) {
508
509 int property = GetterUtil.getInteger(
510 properties.getProperty(propertyName + "[" + container + "]"),
511 defaultValue);
512
513 if (property > maxValue) {
514 property = maxValue;
515 }
516
517 if (_log.isInfoEnabled()) {
518 _log.info(
519 "Default " + prettyPropertyName + " for " + container +
520 " configured to " + property);
521 }
522
523 return property;
524 }
525
526 protected long getSeekTimeStamp(int percentage) throws Exception {
527 IContainer inputIContainer = getInputIContainer();
528
529 long seekTimeStamp = -1;
530
531 long videoSeconds = inputIContainer.getDuration() / 1000000L;
532
533 long seekSeconds = ((videoSeconds * percentage) / 100L);
534
535 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
536 IStream inputIStream = inputIContainer.getStream(i);
537
538 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
539
540 if (inputIStreamCoder.getCodecType() !=
541 ICodec.Type.CODEC_TYPE_VIDEO) {
542
543 continue;
544 }
545
546 IRational iRational = inputIStream.getTimeBase();
547
548 long timeStampOffset =
549 iRational.getDenominator() / iRational.getNumerator() *
550 seekSeconds;
551
552 seekTimeStamp = inputIContainer.getStartTime() + timeStampOffset;
553
554 break;
555 }
556
557 return seekTimeStamp;
558 }
559
560 protected long getStreamTimeStampOffset(IStream iStream) {
561 long timeStampOffset = 0;
562
563 if ((iStream.getStartTime() != Global.NO_PTS) &&
564 (iStream.getStartTime() > 0) && (iStream.getTimeBase() != null)) {
565
566 IRational iRational = IRational.make(
567 1, (int)Global.DEFAULT_PTS_PER_SECOND);
568
569 timeStampOffset = iRational.rescale(
570 iStream.getStartTime(), iStream.getTimeBase());
571 }
572
573 return timeStampOffset;
574 }
575
576 protected boolean isKeyPacketFound(
577 IPacket inputIPacket, boolean keyPacketFound) {
578
579 if (inputIPacket.isKey() && !keyPacketFound) {
580 return true;
581 }
582
583 return keyPacketFound;
584 }
585
586 protected boolean isStartDecoding(
587 IPacket inputIPacket, IStreamCoder inputIStreamCoder,
588 boolean keyPacketFound, int nonKeyAfterKeyCount,
589 boolean onlyDecodeKeyPackets) {
590
591 if (onlyDecodeKeyPackets && !inputIPacket.isKey()) {
592 return false;
593 }
594
595 ICodec.ID iCodecID = inputIStreamCoder.getCodecID();
596
597 if (iCodecID.equals(ICodec.ID.CODEC_ID_MJPEG)) {
598 return true;
599 }
600 else if (iCodecID.equals(ICodec.ID.CODEC_ID_MPEG2VIDEO) ||
601 iCodecID.equals(ICodec.ID.CODEC_ID_THEORA)) {
602
603 if (nonKeyAfterKeyCount != 1) {
604 return true;
605 }
606
607 return false;
608 }
609
610 return keyPacketFound;
611 }
612
613 protected void openContainer(
614 IContainer iContainer, String url, boolean writeContainer)
615 throws Exception {
616
617 int value = 0;
618
619 if (writeContainer) {
620 value = iContainer.open(url, IContainer.Type.WRITE, null);
621 }
622 else {
623 value = iContainer.open(url, IContainer.Type.READ, null);
624 }
625
626 if (value < 0) {
627 if (writeContainer) {
628 throw new RuntimeException("Unable to open output URL");
629 }
630 else {
631 throw new RuntimeException("Unable to open input URL");
632 }
633 }
634 }
635
636 protected void openStreamCoder(IStreamCoder iStreamCoder) throws Exception {
637 if ((iStreamCoder != null) &&
638 (iStreamCoder.getCodecType() != ICodec.Type.CODEC_TYPE_UNKNOWN)) {
639
640 int result = iStreamCoder.setStandardsCompliance(
641 IStreamCoder.CodecStandardsCompliance.COMPLIANCE_EXPERIMENTAL);
642
643 if (result < 0) {
644 throw new RuntimeException(
645 "Unable to set compliance mode to experimental");
646 }
647
648 if (iStreamCoder.open(null, null) < 0) {
649 throw new RuntimeException("Unable to open coder");
650 }
651 }
652 }
653
654 protected void prepareAudio(
655 IAudioResampler[] iAudioResamplers,
656 IAudioSamples[] inputIAudioSamples,
657 IAudioSamples[] outputIAudioSamples, IStreamCoder inputIStreamCoder,
658 IStreamCoder[] outputIStreamCoders, IContainer outputIContainer,
659 IStream[] outputIStreams, ICodec.Type inputICodecType,
660 String outputURL, int index)
661 throws Exception {
662
663 ICodec iCodec = getAudioEncodingICodec(outputIContainer);
664
665 if (iCodec == null) {
666 iCodec = ICodec.guessEncodingCodec(
667 null, null, outputURL, null, inputICodecType);
668 }
669
670 if (iCodec == null) {
671 throw new RuntimeException(
672 "Unable to determine " + inputICodecType + " encoder for " +
673 outputURL);
674 }
675
676 IStream outputIStream = outputIContainer.addNewStream(iCodec);
677
678 outputIStreams[index] = outputIStream;
679
680 IStreamCoder outputIStreamCoder = outputIStream.getStreamCoder();
681
682 outputIStreamCoders[index] = outputIStreamCoder;
683
684 int bitRate = inputIStreamCoder.getBitRate();
685
686 if (_log.isInfoEnabled()) {
687 _log.info("Original audio bitrate " + bitRate);
688 }
689
690 bitRate = getAudioBitRate(iCodec, bitRate);
691
692 if (_log.isInfoEnabled()) {
693 _log.info("Modified audio bitrate " + bitRate);
694 }
695
696 outputIStreamCoder.setBitRate(bitRate);
697
698 int channels = getAudioEncodingChannels(
699 outputIContainer, inputIStreamCoder.getChannels());
700
701 outputIStreamCoder.setChannels(channels);
702
703 outputIStreamCoder.setGlobalQuality(0);
704
705 Format sampleFormat = inputIStreamCoder.getSampleFormat();
706
707 if (_log.isInfoEnabled()) {
708 _log.info(
709 "Original audio sample format " + sampleFormat.toString());
710 }
711
712 sampleFormat = getAudioSampleFormat(iCodec, sampleFormat);
713
714 if (_log.isInfoEnabled()) {
715 _log.info(
716 "Modified audio sample format " + sampleFormat.toString());
717 }
718
719 outputIStreamCoder.setSampleFormat(sampleFormat);
720
721 outputIStreamCoder.setSampleRate(getAudioSampleRate());
722
723 iAudioResamplers[index] = createIAudioResampler(
724 inputIStreamCoder, outputIStreamCoder);
725
726 inputIAudioSamples[index] = IAudioSamples.make(
727 1024, inputIStreamCoder.getChannels(),
728 inputIStreamCoder.getSampleFormat());
729 outputIAudioSamples[index] = IAudioSamples.make(
730 1024, outputIStreamCoder.getChannels(),
731 outputIStreamCoder.getSampleFormat());
732 }
733
734 protected IAudioSamples resampleAudio(
735 IAudioResampler iAudioResampler, IAudioSamples inputIAudioSample,
736 IAudioSamples resampledIAudioSample)
737 throws Exception {
738
739 if ((iAudioResampler == null) ||
740 (inputIAudioSample.getNumSamples() <= 0)) {
741
742 return inputIAudioSample;
743 }
744
745 iAudioResampler.resample(
746 resampledIAudioSample, inputIAudioSample,
747 inputIAudioSample.getNumSamples());
748
749 return resampledIAudioSample;
750 }
751
752 protected IVideoPicture resampleVideo(
753 IVideoResampler iVideoResampler, IVideoPicture inputIVideoPicture,
754 IVideoPicture resampledIVideoPicture)
755 throws Exception {
756
757 if (iVideoResampler == null) {
758 return inputIVideoPicture;
759 }
760
761 if (iVideoResampler.resample(
762 resampledIVideoPicture, inputIVideoPicture) < 0) {
763
764 throw new RuntimeException("Unable to resample video");
765 }
766
767 return resampledIVideoPicture;
768 }
769
770 protected void rewind() throws Exception {
771 IContainer inputIContainer = getInputIContainer();
772
773 if (inputIContainer == null) {
774 return;
775 }
776
777 int value = 0;
778
779 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
780 IStream inputIStream = inputIContainer.getStream(i);
781
782 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
783
784 if (inputIStreamCoder.getCodecType() !=
785 ICodec.Type.CODEC_TYPE_VIDEO) {
786
787 continue;
788 }
789
790 value = rewind(i);
791
792 if (value < 0) {
793 throw new RuntimeException("Error while seeking file");
794 }
795
796 break;
797 }
798 }
799
800 protected int rewind(int index) throws Exception {
801 IContainer inputIContainer = getInputIContainer();
802
803 if (inputIContainer == null) {
804 return -1;
805 }
806
807 int value = inputIContainer.seekKeyFrame(index, -1, 0);
808
809 if (value < 0) {
810 throw new RuntimeException("Error while seeking file");
811 }
812
813 return value;
814 }
815
816 protected int seek(int index, long timeStamp) throws Exception {
817 IContainer inputIContainer = getInputIContainer();
818
819 if (inputIContainer == null) {
820 return -1;
821 }
822
823 int value = inputIContainer.seekKeyFrame(index, timeStamp, 0);
824
825 if (value < 0) {
826 throw new RuntimeException("Error while seeking file");
827 }
828
829 return value;
830 }
831
832 protected long seek(long timeStamp) throws Exception {
833 IContainer inputIContainer = getInputIContainer();
834
835 if (inputIContainer == null) {
836 return -1;
837 }
838
839 int value = 0;
840
841 for (int i = 0; i < inputIContainer.getNumStreams(); i++) {
842 IStream inputIStream = inputIContainer.getStream(i);
843
844 IStreamCoder inputIStreamCoder = inputIStream.getStreamCoder();
845
846 if (inputIStreamCoder.getCodecType() !=
847 ICodec.Type.CODEC_TYPE_VIDEO) {
848
849 continue;
850 }
851
852 value = seek(i, timeStamp);
853
854 if (value < 0) {
855 throw new RuntimeException("Error while seeking file");
856 }
857
858 break;
859 }
860
861 return value;
862 }
863
864 protected void updateAudioTimeStamp(
865 IAudioSamples inputAudioSample, long timeStampOffset) {
866
867 if (inputAudioSample.getTimeStamp() != Global.NO_PTS) {
868 inputAudioSample.setTimeStamp(
869 inputAudioSample.getTimeStamp() - timeStampOffset);
870 }
871 }
872
873 protected void updateVideoTimeStamp(
874 IVideoPicture inputIVideoPicture, long timeStampOffset) {
875
876 if (inputIVideoPicture.getTimeStamp() != Global.NO_PTS) {
877 inputIVideoPicture.setTimeStamp(
878 inputIVideoPicture.getTimeStamp() - timeStampOffset);
879 }
880 }
881
882 protected static final int AUDIO_BIT_RATE_DEFAULT = 64000;
883
884 protected static final int AUDIO_BIT_RATE_MAX = 500000;
885
886 protected static final int AUDIO_SAMPLE_RATE_DEFAULT = 44100;
887
888 protected static final int AUDIO_SAMPLE_RATE_MAX = 192000;
889
890 protected static final int DECODE_VIDEO_THUMBNAIL = 2;
891
892 private static final Log _log = LogFactoryUtil.getLog(
893 LiferayConverter.class);
894
895 private ConverterFactory.Type _converterFactoryType;
896 private IConverter _videoIConverter;
897
898 }