ImageToMovie.java
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, AIST, the University of Tokyo and General Robotix Inc.
3  * All rights reserved. This program is made available under the terms of the
4  * Eclipse Public License v1.0 which accompanies this distribution, and is
5  * available at http://www.eclipse.org/legal/epl-v10.html
6  * Contributors:
7  * General Robotix Inc.
8  * National Institute of Advanced Industrial Science and Technology (AIST)
9  */
10 package com.generalrobotix.ui.view.tdview;
11 
12 import java.io.*;
13 import java.util.*;
14 import java.awt.*;
15 
16 import javax.media.*;
17 import javax.media.control.*;
18 import javax.media.protocol.*;
19 import javax.media.datasink.*;
20 import javax.media.format.*;
21 import javax.media.util.ImageToBuffer;
22 
23 import org.eclipse.jface.dialogs.MessageDialog;
24 import org.eclipse.swt.widgets.Display;
25 
28 
29 
30 //======================================================================
31 //ImageToMovie
32 //
33 //フィールド
34 // public static String QUICKTIME
35 // .mov形式
36 // public static String MSVIDEO
37 // .avi形式
38 //
39 //コンストラクタ
40 // public ImageToMovie (int width, int height, float frameRate,String outputUrl,String fileType){
41 // 引数の説明
42 // width,height ムービーサイズ
43 // frameRate フレームレート[1/s]
44 // outputUrl ファイル名
45 // fileType ファイルタイプ
46 // QUICKTIME or MSVIDEO
47 //
48 //メソッド
49 // public Format[] getSupportedFormats()
50 // 出力可能なFormatを配列として返す。
51 //
52 // public void setFormat(Format format)
53 // 出力形式を設定する。
54 //
55 // public void startProcess()
56 // 処理を開始する。
57 //
58 // public void pushImage(Image image){
59 // ムービーの一コマのイメージを追加する
60 //
61 // public int getImageStackSize(){
62 // 現在バッファにスタックされているイメージ数を返す
63 //
64 // public void endProcess(){
65 // ムービー作成のが終了する。
66 // (バッファにたまっている画像を出力して終わる。ファイルが閉じられれるまでwaitする事に注意)
67 //
68 //======================================================================
69 
70 
71 public class ImageToMovie implements ControllerListener, DataSinkListener {
72  //ファイル形式用定数
73  public static String QUICKTIME=FileTypeDescriptor.QUICKTIME;
74  public static String MSVIDEO=FileTypeDescriptor.MSVIDEO;
75 
76  private ImageDataSource ids_;//カスタムデータソース
77  private Processor p_;//プロセッサ
78  private DataSink dsink_;//データシンク
79  private MediaLocator outML_;//出力ファイル
80 
81  private final boolean debugFlag_ = false;//デバッグ用
82 
83  //待ち用
84  private Object waitSync_ = new Object();
85  private boolean stateTransitionOK_ = true;
86  private Object waitFileSync_ = new Object();
87  private boolean fileDone_ = false;
88  private boolean fileSuccess_ = true;
89 
90 
91  // Create a media locator from the given string.
92  static MediaLocator createMediaLocator(String url) {
93 
94  MediaLocator ml;
95 
96  if (url.indexOf(":") > 0 && (ml = new MediaLocator(url)) != null)
97  return ml;
98 
99  if (url.startsWith(File.separator)) {
100  if ((ml = new MediaLocator("file:" + url)) != null)
101  return ml;
102  } else {
103  String file =
104  "file:" + System.getProperty("user.dir") + File.separator + url;
105  if ((ml = new MediaLocator(file)) != null) return ml;
106  }
107 
108  return null;
109  }
110 
111  //コンストラクタ
112  //出力用MediaLocatorとプロセッサとデータソースを作りファイル作成の準備までする
113  public ImageToMovie (
114  int width,
115  int height,
116  float frameRate,
117  String outputUrl,
118  String fileType
119  ){
120  //出力用MediaLocator生成
121  outML_ = createMediaLocator(outputUrl);
122  if (debugFlag_) System.out.println("create:"+outML_);
123 
124 
125  //データソース生成
126  ids_ = new ImageDataSource(width, height, frameRate);
127 
128  //プロセッサ生成
129  try {
130  if (debugFlag_) {
131  System.err.println(
132  "- create processor for the image datasource ..."
133  );
134  }
135  p_ = Manager.createProcessor(ids_);
136  } catch (Exception e) {
137  System.err.println(
138  "Yikes! Cannot create a processor from the data source."
139  );
140  return;
141  }
142 
143 
144  p_.addControllerListener(this);
145 
146  // Put the Processor into configured state so we can set
147  // some processing options on the processor.
148  p_.configure();
149  if (!_waitForState(p_, Processor.Configured)) {
150  System.err.println("Failed to configure the processor.");
151  return ;
152  }
153 
154  // Set the output content descriptor to.
155  p_.setContentDescriptor(new ContentDescriptor(fileType));
156  }
157 
158  //使用可能な形式を返す
159  public Format[] getSupportedFormats(){
160  TrackControl tcs[] = p_.getTrackControls();
161  return tcs[0].getSupportedFormats();
162  }
163 
164  //形式を設定
165  public void setFormat(Format format){
166  TrackControl tcs[] = p_.getTrackControls();
167  tcs[0].setFormat(format);
168  }
169 
170  //ムービー処理開始
171  public boolean startProcess() {
172  p_.realize();
173  if (!_waitForState(p_, Controller.Realized)) {
174  System.err.println("Failed to realize the processor.");
175  return false;
176  }
177  // Now, we'll need to create a DataSink.
178  if ((dsink_ = _createDataSink(p_, outML_)) == null) {
179  System.err.println(
180  "Failed to create a DataSink for the given output " +
181  "MediaLocator: " + outML_
182  );
183  return false;
184  }
185  dsink_.addDataSinkListener(this);
186  fileDone_ = false;
187 
188  if (debugFlag_) System.err.println("start processing...");
189 
190  // OK, we can now start the actual transcoding.
191  try {
192  p_.start();
193  dsink_.start();
194  } catch (IOException e) {
195  System.err.println("IO error during processing");
196  return false;
197  }
198  return true;
199  }
200 
201 
202  //イメージセットメソッド
203  public void pushImage(Image image){
204  ids_.pushImage(image);
205  }
206 
207  //現在バッファにスタックされているイメージ数を返す
208  public int getImageStackSize(){
209  return ids_.getImageStackSize();
210  }
211 
212  //終了させる
213  public void endProcess(){
214  ids_.endImage();
215 
216  _waitForFileDone();
217 
218  // Cleanup.
219  try {
220  dsink_.close();
221  } catch (Exception ex) {}
222  p_.removeControllerListener(this);
223 
224  if (debugFlag_) System.err.println("...done processing.");
225 
226  }
227 
228 
229  //DataSinkを作成する下請け関数
230  private DataSink _createDataSink(Processor p, MediaLocator outML) {
231 
232  DataSource ds;
233 
234  if ((ds = p.getDataOutput()) == null) {
235  System.err.println(
236  "Something is really wrong: the processor does not have " +
237  "an output DataSource"
238  );
239  return null;
240  }
241 
242  DataSink dsink;
243 
244  try {
245  if (debugFlag_) {
246  System.err.println("- create DataSink for: " + outML);
247  }
248  dsink = Manager.createDataSink(ds, outML);
249  dsink.open();
250  } catch (Exception e) {
251  System.err.println("Cannot create the DataSink: " + e);
252  Display display = Display.getDefault();
253  if (display != null && !display.isDisposed()) {
254  display.syncExec(new Runnable(){
255  public void run(){
256  MessageDialog.openError( GrxUIPerspectiveFactory.getCurrentShell(), MessageBundle.get("Grx3DView.dialog.title.error"), MessageBundle.get("Grx3DView.dialog.message.recFileError")); //$NON-NLS-1$ //$NON-NLS-2$
257  }
258  });
259  }
260  return null;
261  }
262 
263  return dsink;
264  }
265 
266 
267  //* Block until the processor has transitioned to the given state.
268  //* Return false if the transition failed.
269  boolean _waitForState(Processor p, int state) {
270  synchronized (waitSync_) {
271  try {
272  while (p.getState() < state && stateTransitionOK_)
273  waitSync_.wait();
274  } catch (Exception e) {}
275  }
276  return stateTransitionOK_;
277  }
278 
279 
280  //* Controller Listener.
281  public void controllerUpdate(ControllerEvent evt) {
282 
283  if (evt instanceof ConfigureCompleteEvent ||
284  evt instanceof RealizeCompleteEvent ||
285  evt instanceof PrefetchCompleteEvent) {
286  synchronized (waitSync_) {
287  stateTransitionOK_ = true;
288  waitSync_.notifyAll();
289  }
290  } else if (evt instanceof ResourceUnavailableEvent) {
291  synchronized (waitSync_) {
292  stateTransitionOK_ = false;
293  waitSync_.notifyAll();
294  }
295  } else if (evt instanceof EndOfMediaEvent) {
296  evt.getSourceController().stop();
297  evt.getSourceController().close();
298  }
299  }
300 
301 
302 
303 
304  // Block until file writing is done.
305  boolean _waitForFileDone() {
306  synchronized (waitFileSync_) {
307  try {
308  while (!fileDone_)
309  waitFileSync_.wait();
310  } catch (Exception e) {}
311  }
312  return fileSuccess_;
313  }
314 
315 
316  //Event handler for the file writer.
317  public void dataSinkUpdate(DataSinkEvent evt) {
318 
319  if (evt instanceof EndOfStreamEvent) {
320  synchronized (waitFileSync_) {
321  fileDone_ = true;
322  waitFileSync_.notifyAll();
323  }
324  } else if (evt instanceof DataSinkErrorEvent) {
325  synchronized (waitFileSync_) {
326  fileDone_ = true;
327  fileSuccess_ = false;
328  waitFileSync_.notifyAll();
329  }
330  }
331  }
332 
333 
335  // Inner classes.
337  class ImageDataSource extends PullBufferDataSource {
338 
339  ImageSourceStream streams_[];
340 
341  ImageDataSource(int width, int height, float frameRate) {
342  streams_ = new ImageSourceStream[1];
343  streams_[0] = new ImageSourceStream(width, height, frameRate);
344  }
345  //イメージセットメソッド
346  public void pushImage(Image image){
347  streams_[0].pushImage(image);
348  }
349 
350  //現在バッファにスタックされているイメージ数を返す
351  public int getImageStackSize(){
352  return streams_[0].getImageStackSize();
353  }
354 
355  //終了させる
356  public void endImage(){
357  streams_[0].endImage();
358  }
359 
360  public void setLocator(MediaLocator source) {
361  }
362 
363  public MediaLocator getLocator() {
364  return null;
365  }
366 
367  //Content type is of RAW since we are sending buffers of video
368  // frames without a container format.
369  public String getContentType() {
370  return ContentDescriptor.RAW;
371  }
372 
373  public void connect() {
374  }
375 
376  public void disconnect() {
377  }
378 
379  public void start() {
380  }
381 
382  public void stop() {
383  }
384 
385  public PullBufferStream[] getStreams() {
386  return streams_;
387  }
388 
389  public javax.media.Time getDuration() {
390  return DURATION_UNKNOWN;
391  }
392 
393  public Object[] getControls() {
394  return new Object[0];
395  }
396 
397  public Object getControl(String type) {
398  return null;
399  }
400  }
401 
402 
403  // The source stream to go along with ImageDataSource.
404  class ImageSourceStream implements PullBufferStream {
405 
406  int width_, height_;
407  float frameRate_;
408  VideoFormat format_;
409  //Format format_;
410  Vector<Buffer> imageStack_; //イメージを貯えておくスタック
411  boolean ending_ = false;//終了の要請あり
412  boolean ended_ = false;//終了した
413 
414  public ImageSourceStream(int width, int height, float frameRate) {
415  this.width_ = width;
416  this.height_ = height;
417  frameRate_=frameRate;
418 
419  imageStack_= new Vector<Buffer>();
420 
421  format_ =
422  new RGBFormat(
423  new Dimension(width, height),
424  Format.NOT_SPECIFIED,
425  Format.intArray,
426  (float)frameRate,
427  32,
428  0xff0000,
429  0x00ff00,
430  0x0000ff
431  );
432  }
433 
434  //イメージセットメソッド
435  public void pushImage(Image image){
436  imageStack_.add(ImageToBuffer.createBuffer(image, frameRate_));
437  }
438 
439  //終了させる
440  public void endImage(){
441  ending_=true;
442  }
443 
444  //現在バッファにスタックされているイメージ数を返す
445  public int getImageStackSize(){
446  return imageStack_.size();
447  }
448 
449  //イメージがセットされていればブロック解除
450  //作者注:特に動作していないようです
451  public boolean willReadBlock() {
452  //System.out.println("willReadBlock");
453  return (ending_==false && imageStack_.isEmpty());
454  //return false;
455  }
456 
457  // This is called from the Processor to read a frame worth
458  // of video data.
459  public void read(Buffer buf) throws IOException {
460 
461  // 終了の知らせあり
462  if (ending_ && imageStack_.isEmpty()) {
463  // We are done. Set EndOfMedia.
464  System.err.println("Done reading all images.");
465  buf.setEOM(true);
466  buf.setOffset(0);
467  buf.setLength(0);
468  ended_=true;
469 
470  //通常の処理
471  } else if (!(imageStack_.isEmpty())){ //スタックにデータあり
472  //スタックからイメージデータを取り出しbufに入れる
473  buf.copy((Buffer)imageStack_.remove(0));
474  buf.setFlags(buf.getFlags() | Buffer.FLAG_KEY_FRAME);
475  buf.setFormat(format_);
476  if (debugFlag_) {
477  /*
478  System.out.println(
479  "flag = " + buf.getFlags() +
480  " format = " + buf.getFormat() +
481  " data = " + buf.getData()
482  );
483  */
484  //System.out.println("writing image to file.");
485  }
486  } else { //スタックにはデータなし
487  //System.err.println("una aho na!.");
488  buf.setFlags(Buffer.FLAG_DISCARD );//ダミーを示すフラグをセット
489  }
490 
491  }
492  public Format getFormat() {
493  return format_;
494  }
495 
496  public ContentDescriptor getContentDescriptor() {
497  return new ContentDescriptor(ContentDescriptor.RAW);
498  }
499 
500  public long getContentLength() {
501  return 0;
502  }
503 
504  public boolean endOfStream() {
505  return ended_;
506  }
507 
508  public Object[] getControls() {
509  return new Object[0];
510  }
511 
512  public Object getControl(String type) {
513  return null;
514  }
515  //
516  //class StackEx extends Stack{
517  // public StackEx(){
518  // super();
519  // }
520  // public Object popFromEnd(){
521  // if (this.empty()){
522  // return null;
523  // }else{
524  // return this.remove(0);
525  // }
526  // }
527  //}
528  }
529 
530 }
static final String get(String key)
png_infop png_charp png_int_32 png_int_32 int * type
Definition: png.h:2332
ImageToMovie(int width, int height, float frameRate, String outputUrl, String fileType)
state
#define null
our own NULL pointer
Definition: IceTypes.h:57
png_bytepp image
Definition: png.h:1772
png_infop png_uint_32 * width
Definition: png.h:2309
png_infop png_uint_32 png_uint_32 * height
Definition: png.h:2309
def run(tree, args)
png_bytep buf
Definition: png.h:2729
png_size_t start
Definition: png.h:1496
DataSink _createDataSink(Processor p, MediaLocator outML)
org


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Sep 8 2022 02:24:03