Tuesday, February 1, 2011

Xuggler: resizing video using MediaTool API

There is a full source code for resizing video with MediaTool API. Look this. Great, thanks!

I added two lines.
// resize
IMediaReader reader = ToolFactory.makeReader(baseURL+this.streamName);
reader.open();
reader.setBufferedImageTypeToGenerate(BufferedImage.TYPE_3BYTE_BGR);
IMediaTool videoResizeTool = new VideoResizeTool(80,60);
IMediaWriter writer = ToolFactory.makeWriter(baseURL+this.transcodedStreamName, reader);
SetVideoSizeListener setVideoSizeListener = new SetVideoSizeListener(80, 60);
   
// pipeline reader -> VideoResizeTool -> writer -> setVideoSize
reader.addListener(videoResizeTool);
videoResizeTool.addListener(writer);
writer.addListener(setVideoSizeListener);
while (reader.readPacket() == null){
    do {} while(false);
} 

The line 3 is what I mentioned at the previous post. The line 4 is a little bit tricky. I'm not sure why it works, but without the line 4, I got following errors.
13:15:22.483 [Thread-76] WARN  com.xuggle.xuggler - Got error: picture is not of the same width as this Coder (../../../../../../../csrc/com/xuggle/xuggler/StreamCoder.cpp:1251)
Exception in thread "Thread-76" java.lang.RuntimeException: failed to encode video
        at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:771)
        at com.xuggle.mediatool.MediaWriter.encodeVideo(MediaWriter.java:790)
        at com.xuggle.mediatool.MediaWriter.onVideoPicture(MediaWriter.java:1441)
        at com.xuggle.mediatool.AMediaToolMixin.onVideoPicture(AMediaToolMixin.java:166)
        at com.xuggle.mediatool.MediaToolAdapter.onVideoPicture(MediaToolAdapter.java:169)
        at com.mycompany.xuggler.VideoResizeTool.onVideoPicture(VideoResizeTool.java:35)
        at com.xuggle.mediatool.AMediaToolMixin.onVideoPicture(AMediaToolMixin.java:166)
        at com.xuggle.mediatool.MediaReader.dispatchVideoPicture(MediaReader.java:610)
        at com.xuggle.mediatool.MediaReader.decodeVideo(MediaReader.java:519)
        at com.xuggle.mediatool.MediaReader.readPacket(MediaReader.java:475)
        at com.mycompany.xuggler.MediaProcessingThread.startMediaProcessing(MediaProcessingThread.java:96)
        at com.mycompany.xuggler.MediaProcessingThread.run(MediaProcessingThread.java:30)
Is it because of the difference of versions? I'm using the latest revision 1065 not release 3.4.

2 comments:

  1. Why have you added those lines?

    ReplyDelete
  2. You need to make coder's width and image width the same. I use the code below to resize video:
    mediaReader.addListener(new MediaListenerAdapter() {

    private IVideoResampler videoResampler = null;
    int width = 240;
    int height = 180;

    @Override
    public void onVideoPicture(IVideoPictureEvent event) {

    IVideoPicture pic = event.getPicture();

    if (videoResampler == null) {
    videoResampler = IVideoResampler.make(width, height,
    pic.getPixelType(), pic.getWidth(),
    pic.getHeight(), pic.getPixelType());
    }
    IVideoPicture out = IVideoPicture.make(pic.getPixelType(),
    width, height);
    videoResampler.resample(out, pic);

    IVideoPictureEvent asc = new VideoPictureEvent(event
    .getSource(), out, event.getStreamIndex());
    super.onVideoPicture(asc);
    out.delete();

    }

    });


    mediaReader.addListener(writer);

    writer.addListener(new MediaListenerAdapter() {

    int width = 240;
    int height = 180;

    @Override
    public void onAddStream(IAddStreamEvent event) {
    int streamIndex = event.getStreamIndex();
    IStreamCoder streamCoder = event.getSource().getContainer()
    .getStream(streamIndex).getStreamCoder();
    if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_AUDIO) {
    } else if (streamCoder.getCodecType() == ICodec.Type.CODEC_TYPE_VIDEO) {
    streamCoder.setWidth(width);
    streamCoder.setHeight(height);
    }
    super.onAddStream(event);
    }

    });

    ReplyDelete