home *** CD-ROM | disk | FTP | other *** search
/ Geek 6 / Geek-006.iso / linux / video / xmovie-1.5.3.tar.gz / xmovie-1.5.3.tar / xmovie-1.5.3 / xmovie / filempeg.C < prev    next >
C/C++ Source or Header  |  2000-11-29  |  9KB  |  470 lines

  1. #include "asset.h"
  2. #include "colormodels.h"
  3. #include "file.h"
  4. #include "filempeg.h"
  5. #include "mainwindow.h"
  6. #include "mwindowgui.h"
  7. #include "vframe.h"
  8.  
  9.  
  10.  
  11. FileMPEG::FileMPEG(Asset *asset, File *file)
  12.  : FileBase(asset, file)
  13. {
  14.     reset_parameters();
  15.     asset->format = MPEG;
  16.     asset->byte_order = 0;
  17. }
  18.  
  19. FileMPEG::~FileMPEG()
  20. {
  21.     close_file();
  22. }
  23.  
  24. int FileMPEG::reset_parameters_derived()
  25. {
  26.     file = 0;
  27.     audio_stream = 0;
  28.     video_stream = 0;
  29.     return 0;
  30. }
  31.  
  32. int FileMPEG::open_file()
  33. {
  34. // Copy tables if a file is already opened by MWindow
  35.     if(mwindow->audio_file && mwindow->video_file)
  36.     {
  37.         if(!(file = mpeg3_open_copy(asset->path, 
  38.             (mpeg3_t*)((FileMPEG*)mwindow->audio_file->file)->file)))
  39.         {
  40.             perror("FileMPEG::open_file");
  41.             return 1;
  42.         }
  43.     }
  44.     else
  45.     if(!(file = mpeg3_open(asset->path)))
  46.     {
  47.         perror("FileMPEG::open_file");
  48.         return 1;
  49.     }
  50.  
  51.     mpeg3_set_cpus(file, FileBase::file->cpus);
  52.     mpeg3_set_mmx(file, FileBase::file->use_mmx);
  53.     read_header();
  54.  
  55.     if(!asset->video_data && !asset->audio_data)
  56.     {
  57.         mpeg3_close(file);
  58.         return 3;
  59.     }
  60.     return 0;
  61. }
  62.  
  63. int FileMPEG::close_file_derived()
  64. {
  65.     if(file) mpeg3_close(file);
  66.     file = 0;
  67.     return 0;
  68. }
  69.  
  70. int FileMPEG::set_cpus(int cpus)
  71. {
  72.     if(file) mpeg3_set_cpus(file, cpus);
  73.     return 0;
  74. }
  75.  
  76. int FileMPEG::set_mmx(int use_mmx)
  77. {
  78.     if(file) mpeg3_set_mmx(file, use_mmx);
  79.     return 0;
  80. }
  81.  
  82.  
  83. int FileMPEG::read_header()
  84. {
  85.     if(mpeg3_has_audio(file)) asset->audio_data = 1;
  86.  
  87.     if(asset->audio_data)
  88.     {
  89.         asset->audio_streams = mpeg3_total_astreams(file);
  90.         asset->channels = mpeg3_audio_channels(file, audio_stream);
  91.         asset->rate = mpeg3_sample_rate(file, audio_stream);
  92.         asset->bits = 16;
  93.         asset->signed_ = 1;
  94.         asset->byte_order = internal_byte_order;
  95.     }
  96.  
  97.     if(mpeg3_has_video(file)) asset->video_data = 1;
  98.  
  99.     if(asset->video_data)
  100.     {
  101.         asset->video_streams = mpeg3_total_vstreams(file);
  102.         asset->width = mpeg3_video_width(file, video_stream);
  103.         asset->height = mpeg3_video_height(file, video_stream);
  104.         asset->frame_rate = mpeg3_frame_rate(file, video_stream);
  105.         asset->compression[0] = 0;
  106.     }
  107.     if(asset->channels > 2) asset->channels = 2;
  108.     return 0;
  109. }
  110.  
  111. int FileMPEG::set_video_stream(int stream)
  112. {
  113.     this->video_stream = stream;
  114.     return 0;
  115. }
  116.  
  117. int FileMPEG::set_audio_stream(int stream)
  118. {
  119.     this->audio_stream = stream;
  120.     return 0;
  121. }
  122.  
  123.  
  124. long FileMPEG::get_audio_length()
  125. {
  126.     long result = mpeg3_audio_samples(file, audio_stream);
  127.     return result;
  128. }
  129.  
  130. long FileMPEG::get_video_length()
  131. {
  132.     long result = mpeg3_video_frames(file, video_stream);
  133.     return result;
  134. }
  135.  
  136. int FileMPEG::get_position(double &percentage, double &seconds)
  137. {
  138.     if(file)
  139.     {
  140.         if(asset->video_data)
  141.         {
  142.             percentage = mpeg3_tell_percentage(file);
  143.             seconds = mpeg3_get_time(file);
  144.         }
  145. // Audio only
  146.         else
  147.         if(asset->audio_data)
  148.         {
  149.             percentage = (double)mpeg3_get_sample(file, 0) / mpeg3_audio_samples(file, 0);
  150.             seconds = (double)mpeg3_get_sample(file, 0) / asset->rate;
  151.         }
  152.     }
  153.     else
  154.     {
  155.         percentage = seconds = 0;
  156.     }
  157.  
  158.     return 0;
  159. }
  160.  
  161. long FileMPEG::get_video_position()
  162. {
  163.     return mpeg3_get_frame(file, video_stream);
  164. }
  165.  
  166. long FileMPEG::get_audio_position()
  167. {
  168.     return mpeg3_get_sample(file, audio_stream);
  169. }
  170.  
  171. int FileMPEG::end_of_audio()
  172. {
  173.     return mpeg3_end_of_audio(file, audio_stream);
  174. }
  175.  
  176. int FileMPEG::end_of_video()
  177. {
  178.     return mpeg3_end_of_video(file, video_stream);
  179. }
  180.  
  181. int FileMPEG::set_position(double percentage)
  182. {
  183.     int result = 0;
  184.  
  185.     if(file)
  186.     {
  187.         if(asset->video_data)
  188.             result = mpeg3_seek_percentage(file, percentage);
  189.          else
  190.          if(asset->audio_data)
  191.          {
  192.              result = mpeg3_set_sample(file, (long)(percentage * mpeg3_audio_samples(file, audio_stream)), audio_stream);
  193.          }
  194.     }
  195.  
  196.     return result;
  197. }
  198.  
  199. int FileMPEG::set_audio_position(long x)
  200. {
  201.     audio_position = x;
  202.     return mpeg3_set_sample(file, x, audio_stream);
  203. }
  204.  
  205. int FileMPEG::set_video_position(long x)
  206. {
  207.     video_position = x;
  208.     return mpeg3_set_frame(file, x, video_stream);
  209. }
  210.  
  211. int FileMPEG::drop_frames(int frames)
  212. {
  213.     if(file)
  214.     {
  215.         mpeg3_drop_frames(file, frames, 0);
  216.     }
  217.     return 0;
  218. }
  219.  
  220. int FileMPEG::frame_back()
  221. {
  222.     return mpeg3_previous_frame(file, 0);
  223. }
  224.  
  225.  
  226. // Optimization strategies
  227. int FileMPEG::yuv_copy_possible()
  228. {
  229.     if(mwindow->convert_601 && mwindow->gui->accel_available(BC_YUV420P))
  230.     {
  231.         return 1;
  232.     }
  233.     return 0;
  234. }
  235.  
  236. int FileMPEG::frame_buffer_copy_possible(int color_model)
  237. {
  238.     if(color_model == BC_RGB565 ||
  239.         color_model == BC_BGR888 ||
  240.         color_model == BC_BGR8888)
  241.         return 1;
  242.     else
  243.         return 0;
  244. }
  245.  
  246. int FileMPEG::translate_color_model(int color_model)
  247. {
  248.     switch(color_model)
  249.     {
  250.         case BC_RGB565:
  251.             return MPEG3_RGB565;
  252.             break;
  253.         case BC_BGR888:
  254.             if(mwindow->convert_601) return MPEG3_601_BGR888;
  255.             else return MPEG3_BGR888;
  256.             break;
  257.         case BC_BGR8888:
  258.             if(mwindow->convert_601) return MPEG3_601_BGRA8888;
  259.             else return MPEG3_BGRA8888;
  260.             break;
  261.     }
  262.     return -1;
  263. }
  264.  
  265. int FileMPEG::read_yuv_buffer(char *y_output, 
  266.                     char *u_output, 
  267.                     char *v_output, 
  268.                     int in_x,
  269.                     int in_y, 
  270.                     int in_w, 
  271.                     int in_h)
  272. {
  273.     video_position++;
  274.     return mpeg3_read_yuvframe(file,
  275.         y_output,
  276.         u_output,
  277.         v_output,
  278.         in_x,
  279.         in_y,
  280.         in_w,
  281.         in_h,
  282.         video_stream);
  283. }
  284.  
  285. int FileMPEG::read_frame_buffer(unsigned char **frame_buffer, int w, int h, int bitmap_color_model)
  286. {
  287.     int result;
  288.     if(mwindow->crop_letterbox)
  289.     {
  290.         result = mpeg3_read_frame(file, 
  291.                     frame_buffer, 
  292.                     (asset->width - mwindow->input_w) / 2,
  293.                     (asset->height - mwindow->input_h) / 2,
  294.                     mwindow->input_w,
  295.                     mwindow->input_h,
  296.                     w, 
  297.                     h, 
  298.                     translate_color_model(bitmap_color_model),
  299.                     video_stream);
  300.     }
  301.     else
  302.     {
  303.         result = mpeg3_read_frame(file, 
  304.                     frame_buffer, 
  305.                     0,
  306.                     0,
  307.                     asset->width,
  308.                     asset->height,
  309.                     w, 
  310.                     h, 
  311.                     translate_color_model(bitmap_color_model),
  312.                     video_stream);
  313.     }
  314.     video_position++;
  315.     return result;
  316. }
  317.  
  318. int FileMPEG::read_frame(unsigned char *frame)
  319. {
  320.     int result, i, input_x, input_y, input_w, input_h;
  321.     unsigned char **row_pointers;
  322.     
  323.     if(mwindow->crop_letterbox)
  324.     {
  325.         input_x = (asset->width - mwindow->input_w) / 2;
  326.         input_y = (asset->height - mwindow->input_h) / 2;
  327.         input_w = mwindow->input_w;
  328.         input_h = mwindow->input_h;
  329.     }
  330.     else
  331.     {
  332.         input_x = 0;
  333.         input_y = 0;
  334.         input_w = asset->width;
  335.         input_h = asset->height;
  336.     }
  337.  
  338.     row_pointers = new unsigned char*[asset->height];
  339.     for(i = 0; i < asset->height; i++)
  340.         row_pointers[i] = &frame[i * asset->width * 3];
  341.  
  342.     result = mpeg3_read_frame(file, 
  343.                 row_pointers, 
  344.                 input_x,
  345.                 input_y,
  346.                 input_w,
  347.                 input_h,
  348.                 asset->width, 
  349.                 asset->height, 
  350.                 mwindow->convert_601 ? MPEG3_601_RGB888 : MPEG3_RGB888,
  351.                 video_stream);
  352.     delete row_pointers;
  353.     video_position++;
  354.     return result;
  355. }
  356.  
  357. int FileMPEG::read_audio(char *buffer, long len)
  358. {
  359.     int channel;
  360.     int i, j;
  361.     int result = 0;
  362.     int downmix51 = 0;
  363.     BCBASE_INT16 *output_ptr;
  364.     BCBASE_INT16 *output_end;
  365.     BCBASE_INT16 *input_ptr;
  366.     BCBASE_INT16 *input_end;
  367.     int total_channels;
  368.  
  369.     get_read_buffer(len);
  370. // Zero output channels
  371.     output_ptr = (BCBASE_INT16*)buffer + channel;
  372.     input_ptr = (BCBASE_INT16*)read_buffer;
  373.     input_end = input_ptr + len;
  374.  
  375.     if(mpeg3_audio_channels(file, audio_stream) > asset->channels )
  376.     {
  377.         downmix51 = 1;
  378.         for(channel = 0; channel < asset->channels; channel++)
  379.         {
  380.             output_ptr = (BCBASE_INT16*)buffer + channel;
  381.             output_end = (BCBASE_INT16*)output_ptr + len * asset->channels;
  382.             while(output_ptr < output_end)
  383.             {
  384.                 *output_ptr++ = 0;
  385.             }
  386.         }
  387.     }
  388.     
  389.     total_channels = (downmix51 ? mpeg3_audio_channels(file, audio_stream) : asset->channels);
  390.  
  391.     for(channel = 0; 
  392.         channel < total_channels && !result; 
  393.         channel++)
  394.     {
  395.         if(channel == 0)
  396.             result = mpeg3_read_audio(file, 
  397.                     0, 
  398.                     read_buffer, 
  399.                     channel, 
  400.                     len, 
  401.                     audio_stream);
  402.         else
  403.             result = mpeg3_reread_audio(file, 
  404.                     0, 
  405.                     read_buffer, 
  406.                     channel, 
  407.                     len, 
  408.                     audio_stream);
  409.  
  410. // Prepare for next channel
  411. // Incompatible with percentage seeking
  412. //         if(channel < total_channels - 1 && !result) mpeg3_set_sample(file, 
  413. //                     mpeg3_get_sample(file, 0) - len,
  414. //                     audio_stream);
  415.  
  416. // Interlace the audio for the sound driver.
  417.         if(downmix51)
  418.         {
  419.             input_ptr = (BCBASE_INT16*)read_buffer;
  420.             input_end = input_ptr + len;
  421.  
  422.             switch(channel)
  423.             {
  424.                 case 0: output_ptr = (BCBASE_INT16*)buffer;       break; // Left
  425.                 case 1: output_ptr = (BCBASE_INT16*)buffer;       break; // Center
  426.                 case 2: output_ptr = (BCBASE_INT16*)buffer + 1;   break; // Right
  427.                 case 3: output_ptr = (BCBASE_INT16*)buffer;       break; // Left
  428.                 case 4: output_ptr = (BCBASE_INT16*)buffer + 1;   break; // Right
  429.             }
  430.  
  431.             if(channel == 1)
  432.                 while(input_ptr < input_end)
  433.                 {
  434.                     *output_ptr++ += *input_ptr;
  435.                     *output_ptr++ += *input_ptr++;
  436.                 }
  437.             else
  438.                 while(input_ptr < input_end)
  439.                 {
  440.                     *output_ptr += *input_ptr++;
  441.                     output_ptr += asset->channels;
  442.                 }
  443.         }
  444.         else
  445.         {
  446.             output_ptr = (BCBASE_INT16*)buffer + channel;
  447.             input_ptr = (BCBASE_INT16*)read_buffer;
  448.             input_end = input_ptr + len;
  449.  
  450.             while(input_ptr < input_end)
  451.             {
  452.                 *output_ptr = *input_ptr++;
  453.                 output_ptr += asset->channels;
  454.             }
  455.         }
  456.     }
  457.  
  458.     audio_position += len;
  459.     return 0;
  460. }
  461.  
  462. int FileMPEG::load_into_ram()
  463. {
  464.     if(asset->video_data)
  465.     {
  466. //        quicktime_cache_frames(file, 0);
  467.     }
  468.     return 0;
  469. }
  470.