#include <page_export_mjpeg.h>
Inheritance diagram for ExportMJPEG:


Public Member Functions | |
| ExportMJPEG (PageExport *, KinoCommon *) | |
| Constructor for page. | |
| virtual | ~ExportMJPEG () |
| Destructor for page. | |
| void | loadTools (string directory) |
| void | activateTool (int tool) |
| void | selectTool (int tool) |
Private Member Functions | |
| void | start () |
| Empty methods - here for tracking during development. | |
| gulong | onActivate () |
| Define active widgets. | |
| enum export_result | doExport (PlayList *playlist, int begin, int end, int every, bool preview) |
| start exporting MJPEG | |
| void | createAuthorXml (const char *filename, std::vector< std::string > &nameList, bool split, bool isPal) |
Private Attributes | |
| Preferences & | prefs |
| GtkEntry * | fileEntry |
| GtkMenu * | mjpegFormat |
| GtkEntry * | mjpegVideo |
| GtkEntry * | mjpegAudio |
| GtkEntry * | mjpegMultiplexer |
| GtkMenu * | deinterlaceMenu |
| GtkToggleButton * | splitCheck |
| GtkToggleButton * | cleanupCheck |
| GtkMenu * | mjpegAspect |
| GtkEntry * | mjpegXMLScript |
| bool | hasYuvDeinterlace |
| bool | isAvailable |
| vector< DVDTool * > | m_dvdTools |
Definition at line 40 of file page_export_mjpeg.h.
|
||||||||||||
|
Constructor for page.
Definition at line 133 of file page_export_mjpeg.cc. References activateTool(), cleanupCheck, Export::common, deinterlaceMenu, Preferences::exportMjpegAspect, Preferences::exportMjpegAudioPipe, Preferences::exportMjpegCleanup, Preferences::exportMjpegDeinterlace, Preferences::exportMjpegDvdTool, Preferences::exportMjpegFormat, Preferences::exportMjpegMultiplex, Preferences::exportMjpegSceneSplit, Preferences::exportMjpegVideoPipe, Export::exportPage, fileEntry, PageExport::getWidget(), KinoCommon::getWidget(), hasYuvDeinterlace, loadTools(), lookup_widget(), mjpegAspect, mjpegAudio, mjpegFormat, mjpegMultiplexer, mjpegVideo, on_optionmenu_export_mjpeg_format_changed(), prefs, and splitCheck. 00133 : 00134 Export( _exportPage, _common ), 00135 prefs( Preferences::getInstance() ), 00136 hasYuvDeinterlace( false ), 00137 isAvailable( true ) 00138 { 00139 cerr << "> Creating ExportMJPEG Page" << endl; 00140 00141 // Load the extensible dvdauthor tools 00142 loadTools( DATADIR "/kino/scripts/dvdauthor" ); 00143 string alternate_dir = string( getenv( "HOME" ) ) + string( "/kino/dvdauthor" ); 00144 loadTools( alternate_dir ); 00145 00146 char *kinoHome=getenv("KINO_HOME"); 00147 00148 if(kinoHome) 00149 { 00150 string alternate_dir = string( kinoHome ) + string( "/dvdauthor" ); 00151 loadTools( alternate_dir ); 00152 } 00153 00154 activateTool( prefs.exportMjpegDvdTool ); 00155 00156 /* Get pointers to own controls */ 00157 fileEntry 00158 = GTK_ENTRY( lookup_widget( common->getWidget(), "entry_export_mjpeg_file" ) ); 00159 00160 mjpegFormat 00161 = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), 00162 "optionmenu_export_mjpeg_format" ) ) ) ); 00163 deinterlaceMenu 00164 = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( common->getWidget(), 00165 "optionmenu_export_mjpeg_deinterlace" ) ) ) ); 00166 mjpegVideo 00167 = GTK_ENTRY( lookup_widget( exportPage->getWidget(), 00168 "entry_mjpeg_video" ) ); 00169 mjpegAudio 00170 = GTK_ENTRY( lookup_widget( exportPage->getWidget(), 00171 "entry_mjpeg_audio" ) ); 00172 mjpegMultiplexer 00173 = GTK_ENTRY( lookup_widget( exportPage->getWidget(), 00174 "entry_mjpeg_multiplexer" ) ); 00175 splitCheck 00176 = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(), 00177 "checkbutton_export_mjpeg_split" ) ); 00178 cleanupCheck 00179 = GTK_TOGGLE_BUTTON( lookup_widget( common->getWidget(), 00180 "checkbutton_export_mjpeg_cleanup" ) ); 00181 mjpegAspect 00182 = GTK_MENU( gtk_option_menu_get_menu( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), 00183 "optionmenu_export_aspect_ratio" ) ) ) ); 00184 00185 cerr << "> Initializing MJPEG Export Page settings from Preferences" << endl; 00186 gtk_option_menu_set_history( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), 00187 "optionmenu_export_mjpeg_format" ) ), prefs.exportMjpegFormat ); 00188 GtkWidget* vbox = lookup_widget( GTK_WIDGET( exportPage->getWidget() ), "vbox_export_mjpeg_dvd_options" ); 00189 if ( prefs.exportMjpegFormat == 6 ) 00190 gtk_widget_show( vbox ); 00191 else 00192 gtk_widget_hide( vbox ); 00193 gtk_option_menu_set_history( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), 00194 "optionmenu_export_mjpeg_deinterlace" ) ), prefs.exportMjpegDeinterlace ); 00195 gtk_option_menu_set_history( GTK_OPTION_MENU( lookup_widget( exportPage->getWidget(), 00196 "optionmenu_export_aspect_ratio" ) ) , prefs.exportMjpegAspect ); 00197 gtk_toggle_button_set_active( splitCheck, prefs.exportMjpegSceneSplit ); 00198 gtk_toggle_button_set_active( cleanupCheck, prefs.exportMjpegCleanup ); 00199 gtk_entry_set_text( mjpegVideo, prefs.exportMjpegVideoPipe ); 00200 gtk_entry_set_text( mjpegAudio, prefs.exportMjpegAudioPipe ); 00201 gtk_entry_set_text( mjpegMultiplexer, prefs.exportMjpegMultiplex ); 00202 00203 if ( system( "yuvdeinterlace -h 2> /dev/null" ) == 0 ) 00204 { 00205 hasYuvDeinterlace = true; 00206 GtkWidget *widget = gtk_menu_item_new_with_label( _("YUV Deinterlace") ); 00207 gtk_widget_show( widget ); 00208 gtk_menu_append( deinterlaceMenu, widget ); 00209 widget = gtk_menu_item_new_with_label( _("YUV Deinterlace Film-like") ); 00210 gtk_widget_show( widget ); 00211 gtk_menu_append( deinterlaceMenu, widget ); 00212 } 00213 else if ( system( "yuvdenoise -h 2> /dev/null" ) == 0 ) 00214 { 00215 GtkWidget *widget = gtk_menu_item_new_with_label( _("YUV Denoise (Fast)") ); 00216 gtk_widget_show( widget ); 00217 gtk_menu_append( deinterlaceMenu, widget ); 00218 widget = gtk_menu_item_new_with_label( _("YUV Denoise (Slow)") ); 00219 gtk_widget_show( widget ); 00220 gtk_menu_append( deinterlaceMenu, widget ); 00221 } 00222 gtk_option_menu_set_menu( GTK_OPTION_MENU( lookup_widget( common->getWidget(), 00223 "optionmenu_export_mjpeg_deinterlace" ) ), GTK_WIDGET( deinterlaceMenu ) ); 00224 g_signal_connect ( G_OBJECT( lookup_widget( common->getWidget(), 00225 "optionmenu_export_mjpeg_format" ) ), "changed", 00226 G_CALLBACK ( on_optionmenu_export_mjpeg_format_changed ), this ); 00227 }
|
|
|
Destructor for page.
Definition at line 232 of file page_export_mjpeg.cc. 00233 {
00234 cerr << "> Destroying ExportMJPEG Page" << endl;
00235 }
|
|
|
Definition at line 823 of file page_export_mjpeg.cc. References Export::common, KinoCommon::getWidget(), lookup_widget(), and m_dvdTools. Referenced by ExportMJPEG(). 00824 {
00825 // Get the main widget
00826 GtkWidget * window = common->getWidget();
00827
00828 // Start with the option menu
00829 GtkOptionMenu *option_menu = GTK_OPTION_MENU( lookup_widget( window, "optionmenu_dvd_tools" ) );
00830 GtkMenu *menu = GTK_MENU( gtk_option_menu_get_menu( option_menu ) );
00831
00832 // Create a menu if we don't have one
00833 if ( menu )
00834 {
00835 menu = GTK_MENU( gtk_menu_new( ) );
00836 // Create a "None" menu item
00837 GtkWidget *item = gtk_menu_item_new_with_label( _("None") );
00838 gtk_widget_show( item );
00839 gtk_menu_append( menu, item );
00840 // Creat the other menu items
00841 for ( unsigned int i = 0; i < m_dvdTools.size( ); i ++ )
00842 {
00843 GtkWidget *item = gtk_menu_item_new_with_label( m_dvdTools[ i ] ->m_description.c_str( ) );
00844 gtk_widget_show( item );
00845 gtk_menu_append( menu, item );
00846 }
00847
00848 gtk_option_menu_set_menu( option_menu, GTK_WIDGET( menu ) );
00849 }
00850
00851 // Set the active item
00852 gtk_option_menu_set_history( option_menu, index );
00853 }
|
|
||||||||||||||||||||
|
Definition at line 713 of file page_export_mjpeg.cc. References Export::common, KinoCommon::getPageEditor(), KinoCommon::getTime(), and SMIL::Time::TIME_FORMAT_CLOCK. Referenced by doExport(). 00716 {
00717 if( filename == NULL )
00718 {
00719 std::cerr << ">>> ExportMJPEG::createAuthorXml (file name null)" << std::endl;
00720 return;
00721 }
00722
00723 char filenameBuffer[512];
00724
00725 snprintf( filenameBuffer, sizeof( filenameBuffer ), "%s-dvdauthor.xml", filename );
00726
00727 std::cerr << ">>> ExportMJPEG::createAuthorXml (filename: " << filenameBuffer << ")" << std::endl;
00728
00729 std::stringstream xml;
00730
00731 xml << "<?xml version=\"1.0\"?>" << std::endl;
00732 xml << "<dvdauthor>" << std::endl;
00733
00734 xml << "\t<vmgm>" << std::endl;
00735 xml << "\t\t<menus>" << std::endl;
00736 xml << "\t\t\t<video />" << std::endl;
00737 xml << "\t\t\t<audio />" << std::endl;
00738 xml << "\t\t\t<subpicture lang=\"en\" />" << std::endl;
00739 xml << "\t\t</menus>" << std::endl;
00740 xml << "\t</vmgm>" << std::endl;
00741
00742 xml << "\t<titleset>" << std::endl;
00743 xml << "\t\t<titles>" << std::endl;
00744 xml << "\t\t\t<pgc pause=\"0\">" << std::endl;
00745
00746 std::vector<std::string>::iterator iter = nameList.begin();
00747
00748 if( split == true )
00749 {
00750 /* output the list list of vobs */
00751 while( iter != nameList.end() )
00752 {
00753 xml << "\t\t\t\t<vob file=\"" << *iter << "\" chapters=\"\" pause=\"0\" />" << std::endl;
00754 iter++;
00755 }
00756 }
00757 else
00758 {
00759 /* retrieve the vector of scenes, assuming that the vector
00760 * doesn't have the 0 entry.
00761 */
00762 std::vector<int> sceneStarts = this->common->getPageEditor()->GetScene();
00763 std::vector<int>::iterator sceneIter = sceneStarts.begin();
00764 std::stringstream chapterList;
00765
00766 chapterList << "0";
00767
00768 for( sceneIter = sceneStarts.begin(); sceneIter != sceneStarts.end() - 1; ++sceneIter )
00769 chapterList << "," << this->common->getTime().parseFramesToString( *sceneIter, SMIL::Time::TIME_FORMAT_CLOCK );
00770
00771 /* output the single vob, checking for chapter marks */
00772 xml << "\t\t\t\t<vob file=\"" << *iter << "\" chapters=\"" <<
00773 chapterList.str() << "\" pause=\"0\" />" << std::endl;
00774 }
00775
00776 xml << "\t\t\t</pgc>" << std::endl;
00777 xml << "\t\t</titles>" << std::endl;
00778 xml << "\t</titleset>" <<std::endl;
00779
00780 xml << "</dvdauthor>" << std::endl;
00781
00782 std::cerr << xml.str() << std::endl;
00783
00784 std::ofstream out( filenameBuffer );
00785
00786 if( out.is_open() == true )
00787 {
00788 out << xml.str();
00789 out.flush();
00790 }
00791
00792 out.close();
00793 }
|
|
||||||||||||||||||||||||
|
start exporting MJPEG
Implements Export. Definition at line 290 of file page_export_mjpeg.cc. References AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY, Export::calculateAdjustedRate(), cleanupCheck, DVDTool::close(), KinoAVPipe::CloseAudio(), KinoAVPipe::CloseVideo(), Export::common, KinoAudioFactory::CreateAudioPipe(), createAuthorXml(), KinoVideoFactory::CreateVideoPipe(), deinterlaceMenu, DVDTool::execute(), KinoAVPipe::ExecuteCommand(), EXPORT_RESULT_ABORT, EXPORT_RESULT_FAILURE, EXPORT_RESULT_SUCCESS, Preferences::exportMjpegAspect, Preferences::exportMjpegAudioPipe, Preferences::exportMjpegCleanup, Preferences::exportMjpegDeinterlace, Preferences::exportMjpegDvdTool, Preferences::exportMjpegFormat, Preferences::exportMjpegMultiplex, Preferences::exportMjpegSceneSplit, Preferences::exportMjpegVideoPipe, Export::exportPage, fileEntry, FRAME_MAX_HEIGHT, FRAME_MAX_WIDTH, Frame::GetAudioInfo(), AsyncAudioResample< input_t, output_t >::GetError(), GetFramePool(), AsyncAudioResample< input_t, output_t >::GetOutput(), KinoCommon::getWidget(), hasYuvDeinterlace, info, Export::innerLoopUpdate(), AsyncAudioResample< input_t, output_t >::IsError(), PageExport::isExporting, Frame::IsPAL(), lookup_widget(), m_dvdTools, mjpegAspect, mjpegAudio, mjpegFormat, mjpegMultiplexer, mjpegVideo, modal_message(), KinoAVPipe::OpenAudio(), KinoAVPipe::OpenVideoPipe(), KinoAVPipe::OutputAudioFrame(), KinoAVPipe::OutputVideoFrame(), PIPE_AUDIO_WAV, PIPE_VIDEO_DEINTERLACED_MJPEG, PIPE_VIDEO_MJPEG, pixels, prefs, AsyncAudioResample< input_t, output_t >::Process(), and splitCheck. 00292 {
00293 cerr << ">>> ExportMJPEG::startExport" << endl;
00294
00295 // Set defaults on own controls
00296 prefs.exportMjpegFormat = g_list_index ( GTK_MENU_SHELL ( mjpegFormat ) ->children, gtk_menu_get_active( mjpegFormat ) );
00297 prefs.exportMjpegDeinterlace = g_list_index ( GTK_MENU_SHELL ( deinterlaceMenu ) ->children, gtk_menu_get_active( deinterlaceMenu ) );
00298 prefs.exportMjpegAspect = g_list_index ( GTK_MENU_SHELL ( mjpegAspect ) ->children, gtk_menu_get_active( mjpegAspect ) );
00299 prefs.exportMjpegSceneSplit = gtk_toggle_button_get_active( splitCheck );
00300 prefs.exportMjpegCleanup = gtk_toggle_button_get_active( cleanupCheck );
00301 GtkWidget* widget = lookup_widget( common->getWidget(), "optionmenu_dvd_tools" );
00302 widget = gtk_option_menu_get_menu( GTK_OPTION_MENU( widget ) );
00303 prefs.exportMjpegDvdTool = g_list_index ( GTK_MENU_SHELL( widget )->children, gtk_menu_get_active( GTK_MENU( widget ) ) );
00304
00305 // TODO: Fix this buffer stuff.
00306 gchar *filename;
00307 enum export_result status = EXPORT_RESULT_SUCCESS;
00308
00309 filename = g_strdup( gtk_entry_get_text( fileEntry ) );
00310
00311 if ( !( strcmp( filename, "" ) && strpbrk( filename, "\'" ) == NULL ) )
00312 {
00313 modal_message( _( "You must enter a filename which doesn't contain quotes." ) );
00314 g_free( filename );
00315 return EXPORT_RESULT_FAILURE;
00316 }
00317 unsigned char *pixels = new unsigned char[ FRAME_MAX_WIDTH * FRAME_MAX_HEIGHT * 4 ];
00318 Frame* frame = GetFramePool()->GetFrame();
00319
00320 // Get a sample frame to obtain recording info
00321 // TODO: Sample frames are problematic...
00322 playlist->GetFrame( begin, *frame );
00323 frame->decoder->quality = DV_QUALITY_BEST;
00324
00325 // Get all video and audio info required
00326 int width = frame->GetWidth();
00327 int height = frame->GetHeight();
00328 bool isPAL = frame->IsPAL();
00329 bool isWide = frame->IsWide();
00330 AudioInfo info;
00331 frame->GetAudioInfo( info );
00332 short channels = info.channels;
00333 int frequency = info.frequency;
00334
00335 // vars for collecting audio and video pipe commands
00336 bool split = false;
00337 bool author = false;
00338 bool Usercleanup = true;
00339 kino_video_pipe type = PIPE_VIDEO_MJPEG;
00340 gchar *audiopipe = NULL;
00341 gchar *videopipe = NULL;
00342 gchar *multiplex = NULL;
00343 gchar *cleanup = NULL;
00344
00345 // list to collect the names of the generated mpeg2 files
00346 // this collection only proceeds if we are authoring an
00347 // xml file for use with dvdauthor
00348 std::vector<std::string> nameList;
00349
00350 // MPEG and DIVX translations to commands
00351 // What started off as a simple addition is getting pretty damn messy :-/ - ho hum
00352 // Essentially the important things to remember are that only the 5 variables above
00353 // are populated in the following kludge... (this should move into seprate methods)
00354 const char *videopipeInput = "";
00355 int videoformat = 0;
00356 int deinterlaceRequest = 0;
00357 const char *audioencode = "";
00358 const char *multiplexer = "";
00359 int aspectRatio = 0;
00360 bool isY4Minterlaced = true;
00361
00362 videopipeInput = gtk_entry_get_text( mjpegVideo );
00363 strncpy( prefs.exportMjpegVideoPipe, videopipeInput, sizeof(prefs.exportMjpegVideoPipe) );
00364 GtkWidget *active_item = gtk_menu_get_active( mjpegFormat );
00365 videoformat = g_list_index ( GTK_MENU_SHELL ( mjpegFormat ) ->children, active_item );
00366 audioencode = gtk_entry_get_text( mjpegAudio );
00367 strncpy( prefs.exportMjpegAudioPipe, audioencode, sizeof(prefs.exportMjpegAudioPipe) );
00368 multiplexer = gtk_entry_get_text( mjpegMultiplexer );
00369 strncpy( prefs.exportMjpegMultiplex, multiplexer, sizeof(prefs.exportMjpegMultiplex) );
00370 active_item = gtk_menu_get_active( deinterlaceMenu );
00371 deinterlaceRequest = g_list_index ( GTK_MENU_SHELL ( deinterlaceMenu ) ->children, active_item );
00372 split = gtk_toggle_button_get_active( splitCheck );
00373 Usercleanup = gtk_toggle_button_get_active( cleanupCheck );
00374 /* only necessary to check this option if we are creating DVD video */
00375 if( videoformat == 6 )
00376 {
00377 // Tool 0 is always "None"
00378 author = prefs.exportMjpegDvdTool > 0;
00379 }
00380 active_item = gtk_menu_get_active( mjpegAspect );
00381 aspectRatio = g_list_index ( GTK_MENU_SHELL ( mjpegAspect ) ->children, active_item );
00382
00383 /* force deinterlace on MPEG-1 formats if not specified by user */
00384 if ( videoformat < 3 && deinterlaceRequest == 0 )
00385 deinterlaceRequest = 3;
00386
00387 char deinterlace[ 30 ] = "";
00388 char interlace = '0';
00389 char audioOptions[ 20 ] = "";
00390
00391 switch ( deinterlaceRequest )
00392 {
00393 case 0: // None
00394 interlace = '1';
00395 break;
00396 case 1: // Internal
00397 type = PIPE_VIDEO_DEINTERLACED_MJPEG;
00398 isY4Minterlaced = false;
00399 break;
00400 case 2: // Already deinterlaced
00401 isY4Minterlaced = false;
00402 break;
00403 case 3:
00404 strcpy( deinterlace, hasYuvDeinterlace ? "yuvdeinterlace |" : "yuvdenoise -F -f |" );
00405 break;
00406 case 4:
00407 strcpy( deinterlace, hasYuvDeinterlace ? "yuvdeinterlace -f |" : "yuvdenoise -F |" );
00408 break;
00409 }
00410
00411 if ( !strstr( videopipeInput, "yuvscaler" ) )
00412 {
00413 char scale[ 20 ] = "";
00414 char bitrate[ 20 ] = "";
00415
00416 switch ( videoformat )
00417 {
00418 case 1:
00419 strcpy( scale, "VCD" );
00420 frequency = 44100;
00421 if ( strstr( audioencode, "ffmpeg" ) )
00422 strcpy( audioOptions, "-ar 44100" );
00423 else if ( strstr( audioencode, "mp2enc" ) )
00424 strcpy( audioOptions, "-r 44100" );
00425 break;
00426 case 2:
00427 strcpy( scale, "VCD" );
00428 strcpy( bitrate, "-b 1152" );
00429 frequency = 44100;
00430 if ( strstr( audioencode, "ffmpeg" ) )
00431 strcpy( audioOptions, "-ar 44100" );
00432 else if ( strstr( audioencode, "mp2enc" ) )
00433 strcpy( audioOptions, "-r 44100" );
00434 break;
00435 case 3:
00436 strcpy( bitrate, "-b 4000" );
00437 break;
00438 case 4:
00439 strcpy( scale, "SVCD" );
00440 frequency = 44100;
00441 if ( strstr( audioencode, "ffmpeg" ) )
00442 strcpy( audioOptions, "-ar 44100" );
00443 else if ( strstr( audioencode, "mp2enc" ) )
00444 strcpy( audioOptions, "-r 44100" );
00445 break;
00446 case 5:
00447 strcpy( scale, "SVCD" );
00448 strcpy( bitrate, "-b 2500" );
00449 frequency = 44100;
00450 if ( strstr( audioencode, "ffmpeg" ) )
00451 strcpy( audioOptions, "-ar 44100" );
00452 else if ( strstr( audioencode, "mp2enc" ) )
00453 strcpy( audioOptions, "-r 44100" );
00454 break;
00455 case 6:
00456 videoformat = 8;
00457 strcpy( scale, "" );
00458 if ( strstr( audioencode, "ffmpeg" ) )
00459 {
00460 frequency = 48000;
00461 if ( !strstr( audioencode, " -ab " ) )
00462 sprintf( audioOptions, "%s -ab 192", audioOptions );
00463 }
00464 else if ( strstr( audioencode, "mp2enc" ) )
00465 {
00466 if ( !strstr( audioencode, " -r " ) )
00467 sprintf( audioOptions, "%s -r 48000", audioOptions );
00468 frequency = 48000;
00469 if ( !strstr( audioencode, " -b " ) )
00470 sprintf( audioOptions, "%s -b 224", audioOptions );
00471 }
00472 break;
00473 }
00474
00475 // If the bitrate is specified then remove the defaults above
00476 if ( strstr( videopipeInput, " -b " ) || strstr( videopipeInput, "--video-bitrate" ) )
00477 strcpy( bitrate, "" );
00478
00479 // Yuck (!) - builds the video pipe depending on data collected above...
00480 if ( strcmp( scale, "" ) )
00481 videopipe = g_strdup_printf(
00482 "%s yuvscaler -v 0 -O %s -n %c | %s -f %d -I %c -n %c -a %d %s -o \'%s\'.mpv",
00483 deinterlace,
00484 scale, isPAL ? 'p' : 'n', videopipeInput, videoformat, interlace,
00485 isPAL ? 'p' : 'n', aspectRatio ? aspectRatio : (isWide ? 3 : 2), bitrate, filename );
00486 else
00487 videopipe = g_strdup_printf( "%s %s -f %d -I %c -n %c -a %d %s -o \'%s\'.mpv",
00488 deinterlace, videopipeInput, videoformat, interlace,
00489 isPAL ? 'p' : 'n', aspectRatio ? aspectRatio : (isWide ? 3 : 2), bitrate, filename );
00490 }
00491 else
00492 {
00493 videopipe = g_strdup_printf( "%s %s -f %d -I %c -n %c -o \'%s\'.mpv\n",
00494 deinterlace, videopipeInput, videoformat, interlace,
00495 isPAL ? 'p' : 'n', filename );
00496 }
00497 if ( strstr( audioencode, "ffmpeg" ) )
00498 {
00499 audiopipe = g_strdup_printf( "|%s -f wav -i pipe: %s -y \'%s\'.%s", audioencode, audioOptions,
00500 filename, videoformat == 8 ? "ac3" : "mp2" );
00501 if ( strcmp( multiplexer, "" ) )
00502 {
00503 multiplex = g_strdup_printf( "%s -f %d -o \'%s\'%%s.mpeg \'%s\'.mpv \'%s\'.%s",
00504 multiplexer, videoformat, filename, filename, filename,
00505 videoformat == 8 ? "ac3" : "mp2" );
00506 cleanup = g_strdup_printf( "rm -f \'%s\'.mpv \'%s\'.%s \'%s\'.wav",
00507 filename, filename, videoformat == 8 ? "ac3" : "mp2", filename );
00508 }
00509 }
00510 else if ( strstr( audioencode, "mp2enc" ) )
00511 {
00512 audiopipe = g_strdup_printf( "|%s %s -o \'%s\'.mp2", audioencode, audioOptions, filename );
00513 if ( strcmp( multiplexer, "" ) )
00514 {
00515 multiplex = g_strdup_printf( "%s -f %d -o \'%s\'%%s.mpeg \'%s\'.mpv \'%s\'.mp2",
00516 multiplexer, videoformat, filename, filename, filename );
00517 cleanup = g_strdup_printf( "rm -f \'%s\'.mpv \'%s\'.mp2 \'%s\'.wav",
00518 filename, filename, filename );
00519 }
00520 }
00521
00522 KinoAudioPipe *wav = KinoAudioFactory::CreateAudioPipe( PIPE_AUDIO_WAV );
00523 KinoVideoPipe *video = KinoVideoFactory::CreateVideoPipe( type );
00524 KinoAVPipe *mpeg = new KinoAVPipe( wav, video );
00525
00526 // Iterate through each scene (opening and closing audio pipes as requested)
00527 int scene = 0;
00528
00529 for ( int sceneBegin = begin; sceneBegin <= end && exportPage->isExporting;
00530 scene ++ )
00531 {
00532 gchar *full;
00533 char sceneString[ 20 ];
00534 int sceneEnd = end;
00535 bool userMplexSplit = ( multiplex != NULL && ( strstr( multiplex, "-S" ) ||
00536 strstr( multiplex, "--max-segment-size" ) ) );
00537
00538 // Determine if we need to split by scene or not
00539 // when splitting: Output is generated as fileNNN_MMM.mpeg where NNN is the
00540 // kino scene number and MMM is the mplex split
00541 // when not splitting: Output is generated file as fileMMM.mpeg
00542 sceneString[0] = '\0';
00543 if ( split )
00544 {
00545 sprintf( sceneString, "%03d", scene );
00546 if ( userMplexSplit )
00547 strcat( sceneString, "_%03d" );
00548 sceneEnd = playlist->FindEndOfScene( sceneBegin );
00549 if ( sceneEnd > end )
00550 sceneEnd = end;
00551 }
00552 else if ( userMplexSplit )
00553 {
00554 strcpy( sceneString, "%03d" );
00555 }
00556
00557 if ( author )
00558 {
00559 char tmpFilename[512];
00560
00561 if ( split && userMplexSplit ) {
00562 snprintf( tmpFilename, sizeof( tmpFilename ), "%s%03d_001.mpeg", filename, scene );
00563 } else if ( split ) {
00564 snprintf( tmpFilename, sizeof( tmpFilename ), "%s%03d.mpeg", filename, scene );
00565 } else if ( userMplexSplit ) {
00566 snprintf( tmpFilename, sizeof( tmpFilename ), "%s001.mpeg", filename );
00567 } else {
00568 snprintf( tmpFilename, sizeof( tmpFilename ), "%s.mpeg", filename );
00569 }
00570
00571 nameList.push_back( std::string( tmpFilename ) );
00572 }
00573
00574 cerr << ">>> Generated video pipe '" << videopipe << "'" << endl;
00575 if ( audiopipe )
00576 {
00577 cerr << ">>> Generated audio pipe '" << audiopipe << "'" << endl;
00578 mpeg->OpenAudio( audiopipe, channels, frequency, 2 );
00579 }
00580 mpeg->OpenVideoPipe( videopipe, width, height, isY4Minterlaced );
00581
00582 int imagesize = width * height * 3;
00583
00584 // first call to innerLoopUpdate initializes progress tracker, which
00585 // we want to do because calculateAdjustedRate generates paused time.
00586 innerLoopUpdate( sceneBegin, begin, end, every );
00587
00588 // Determine correct amount of audio for duration
00589 double adjustedRate = 0;
00590 AsyncAudioResample<int16_ne_t,int16_le_t>* resampler = 0;
00591 if ( audiopipe )
00592 {
00593 adjustedRate = calculateAdjustedRate( playlist, frequency, sceneBegin, sceneEnd, every );
00594 if ( !adjustedRate )
00595 status = EXPORT_RESULT_ABORT;
00596
00597 // Setup a resampler
00598 resampler = new AsyncAudioResample<int16_ne_t,int16_le_t>(
00599 AUDIO_RESAMPLE_SRC_SINC_BEST_QUALITY, playlist, frequency, sceneBegin, sceneEnd, every );
00600 if ( resampler->IsError() )
00601 {
00602 std::cerr << ">>> Resampler error: " << resampler->GetError() << std::endl;
00603 exportPage->isExporting = false;
00604 status = EXPORT_RESULT_FAILURE;
00605 break;
00606 }
00607 }
00608
00609 /* Iterate over frames in scene */
00610 for ( int i = sceneBegin, j = 0; i <= sceneEnd && exportPage->isExporting;
00611 i += every, j++ )
00612 {
00613 innerLoopUpdate( i, begin, end, every );
00614 playlist->GetFrame( i, *frame );
00615
00616 if ( audiopipe && resampler )
00617 {
00618 int requestedSamples = frame->CalculateNumberSamples( frequency, j );
00619 int nsamples = resampler->Process( adjustedRate, requestedSamples );
00620 if ( nsamples > 0 && !mpeg->OutputAudioFrame( reinterpret_cast<int16_t *>(resampler->GetOutput()),
00621 nsamples * channels * sizeof(int16_t) ) )
00622 {
00623 modal_message( _( "Error writing to KINO/MJPEG audio filter - aborting." ) );
00624 status = EXPORT_RESULT_FAILURE;
00625 break;
00626 }
00627 }
00628
00629 if ( exportPage->isExporting )
00630 {
00631 if ( type == PIPE_VIDEO_MJPEG )
00632 frame->ExtractYUV( pixels );
00633 else
00634 frame->ExtractRGB( pixels );
00635 if ( !mpeg->OutputVideoFrame( pixels, imagesize ) )
00636 {
00637 modal_message( _( "Error writing to KINO/MJPEG video filter - aborting." ) );
00638 status = EXPORT_RESULT_FAILURE;
00639 break;
00640 }
00641 }
00642 }
00643
00644 if ( status == EXPORT_RESULT_SUCCESS && !exportPage->isExporting )
00645 status = EXPORT_RESULT_ABORT;
00646
00647 if ( !split )
00648 exportPage->isExporting = false;
00649
00650 // Try to finish the stream to create a valid mpeg if possible
00651 if ( audiopipe )
00652 mpeg->CloseAudio();
00653 mpeg->CloseVideo();
00654 delete resampler;
00655 resampler = 0;
00656
00657 if ( status == EXPORT_RESULT_SUCCESS && multiplex != NULL && strcmp( multiplex, "" ) )
00658 {
00659 // expand the template to accomodate the scene splits
00660 full = g_strdup_printf( multiplex, sceneString );
00661 cerr << ">>> Executing '" << full << "'" << endl;
00662 if ( 0 != mpeg->ExecuteCommand( full ) )
00663 {
00664 // If mplex error, use user setting
00665 //do_cleanup = Usercleanup;
00666 }
00667 g_free( full );
00668 }
00669
00670 if ( Usercleanup && cleanup != NULL && strcmp( cleanup, "" ) )
00671 mpeg->ExecuteCommand( cleanup );
00672
00673 // Move to start of next scene
00674 sceneBegin = sceneEnd + 1;
00675 }
00676
00677 if ( status == EXPORT_RESULT_SUCCESS && author )
00678 {
00679 createAuthorXml( filename, nameList, split, isPAL );
00680
00681 // Run the selected tool
00682 // -1 to account for first "None" item
00683 DVDTool *tool = m_dvdTools[ prefs.exportMjpegDvdTool - 1 ];
00684 if ( tool )
00685 {
00686 string dvdauthorFile( string( filename ) + "-dvdauthor.xml" );
00687 if ( tool->execute( dvdauthorFile, string( filename ) ) )
00688 modal_message( _("The dvdauthor script failed, but the MPEG export succeeded.") );
00689 tool->close();
00690 }
00691 }
00692
00693 g_free( filename );
00694 g_free( audiopipe );
00695 g_free( videopipe );
00696 g_free( multiplex );
00697 g_free( cleanup );
00698 delete mpeg;
00699 delete video;
00700 delete wav;
00701 delete[] pixels;
00702
00703 GetFramePool()->DoneWithFrame( frame );
00704
00705 return status;
00706 }
|
|
|
Definition at line 795 of file page_export_mjpeg.cc. References DVDTool::compare(), DVDTool::m_active, and m_dvdTools. Referenced by ExportMJPEG(). 00796 {
00797 char * filename;
00798 struct dirent *entry;
00799
00800 DIR *dir = opendir( directory.c_str( ) );
00801
00802 if ( dir )
00803 {
00804 while ( ( entry = readdir( dir ) ) != NULL )
00805 {
00806 filename = g_strdup_printf( "%s/%s", directory.c_str( ), entry->d_name );
00807 if ( entry->d_name[ 0 ] != '.' )
00808 {
00809 fprintf( stderr, "%s\n", filename );
00810 DVDTool *tool = new DVDTool( filename );
00811 if ( tool->m_active )
00812 m_dvdTools.push_back( tool );
00813 else
00814 delete tool;
00815 }
00816 g_free( filename );
00817 }
00818 closedir( dir );
00819 }
00820 std::sort( m_dvdTools.begin(), m_dvdTools.end(), DVDTool::compare );
00821 }
|
|
|
Define active widgets. If mjpegtools are not installed, do not support any common functions. Reimplemented from Export. Definition at line 280 of file page_export_mjpeg.cc. References EXPORT_EXPORT, EXPORT_PAUSE, EXPORT_SCENE_LIST, and isAvailable. 00281 {
00282 if ( isAvailable )
00283 return EXPORT_EXPORT | EXPORT_PAUSE | EXPORT_SCENE_LIST;
00284 return 0;
00285 }
|
|
|
|
|
|
Empty methods - here for tracking during development.
Reimplemented from Export. Definition at line 237 of file page_export_mjpeg.cc. References Export::common, Preferences::exportMjpegFormat, KinoCommon::getWidget(), isAvailable, lookup_widget(), prefs, and KinoCommon::setStatusBar(). 00238 {
00239 // Show DVD options if applicable
00240 GtkWidget* vbox = lookup_widget( common->getWidget(), "vbox_export_mjpeg_dvd_options" );
00241 if ( prefs.exportMjpegFormat == 6 )
00242 gtk_widget_show( vbox );
00243 else
00244 gtk_widget_hide( vbox );
00245
00246 // Disable UI if mjpegtools not installed.
00247 vbox = lookup_widget( common->getWidget(), "vbox_export_mjpeg" );
00248 const char* errorMessage = _( "Failed to execute %s. MPEG export requires a complete installation of mjpegtools." );
00249 if ( system( "which mpeg2enc > /dev/null 2> /dev/null" ) )
00250 {
00251 gtk_widget_set_sensitive( vbox, FALSE );
00252 common->setStatusBar( errorMessage, "mpeg2enc" );
00253 isAvailable = false;
00254 return;
00255 }
00256 if ( system( "which mp2enc > /dev/null 2> /dev/null" ) )
00257 {
00258 gtk_widget_set_sensitive( vbox, FALSE );
00259 common->setStatusBar( errorMessage, "mp2enc" );
00260 isAvailable = false;
00261 return;
00262 }
00263 if ( system( "which mplex > /dev/null 2> /dev/null" ) )
00264 {
00265 gtk_widget_set_sensitive( vbox, FALSE );
00266 common->setStatusBar( errorMessage, "mplex" );
00267 isAvailable = false;
00268 return;
00269 }
00270
00271 // Otherwise, enable UI
00272 isAvailable = true;
00273 gtk_widget_set_sensitive( vbox, TRUE );
00274 }
|
|
|
Definition at line 53 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 51 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 44 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 56 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 57 of file page_export_mjpeg.h. Referenced by onActivate(), and start(). |
|
|
Definition at line 58 of file page_export_mjpeg.h. Referenced by activateTool(), doExport(), and loadTools(). |
|
|
Definition at line 54 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 49 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 47 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 50 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 48 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
|
|
Definition at line 55 of file page_export_mjpeg.h. |
|
|
Definition at line 43 of file page_export_mjpeg.h. Referenced by doExport(), ExportMJPEG(), and start(). |
|
|
Definition at line 52 of file page_export_mjpeg.h. Referenced by doExport(), and ExportMJPEG(). |
1.4.2