X-Git-Url: http://git.cinelerra-gg.org/git/?p=goodguy%2Fhistory.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Ffileogg.C;h=99995fe975711988a77aec82167f866e9b3851c2;hp=e88fd3ce2f372662cb47f45d17bbc9f140a2d079;hb=2e48b660e37eb5c661264d601211e16cb6cd6e89;hpb=49f85559268fc040fe7ba5611cc0520793cf728b diff --git a/cinelerra-5.1/cinelerra/fileogg.C b/cinelerra-5.1/cinelerra/fileogg.C index e88fd3ce..99995fe9 100644 --- a/cinelerra-5.1/cinelerra/fileogg.C +++ b/cinelerra-5.1/cinelerra/fileogg.C @@ -100,10 +100,8 @@ FileOGG::~FileOGG() } void FileOGG::get_parameters(BC_WindowBase *parent_window, - Asset *asset, - BC_WindowBase* &format_window, - int audio_options, - int video_options) + Asset *asset, BC_WindowBase* &format_window, + int audio_options, int video_options, EDL *edl) { if(audio_options) { @@ -1233,78 +1231,53 @@ int FileOGG::ogg_get_page_of_frame(sync_window_t *sw, long serialno, ogg_page *o } -int FileOGG::ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *keyframe_number) +int FileOGG::ogg_seek_to_keyframe(sync_window_t *sw, long serialno, int64_t frame, int64_t *position) { +//printf("seek %jd\n", frame); ogg_page og; ogg_packet op; -// printf("Searching for the proper position to start decoding frame %lli\n", frame); - if (!ogg_get_page_of_frame(sw, serialno, &og, frame)) - { - eprintf(_("FileOGG: Seeking to frame failed\n")); + + if( !ogg_get_page_of_frame(sw, serialno, &og, frame) ) { + eprintf(_("FileOGG: seek to frame failed\n")); return 0; } - // TODO: if the frame we are looking for continoues on the next page, we don't need to do this - // Now go to previous page in order to find out the granulepos - // Don't do it in case this is the first page. -// printf("GP: %lli\n", ogg_page_granulepos(&og)); + // find a page with packets + while( ogg_page_packets(&og) == 0 ) { + ogg_get_prev_page(sw, serialno, &og); + } int64_t granulepos = ogg_page_granulepos(&og); - int64_t iframe = granulepos >> theora_keyframe_granule_shift; - //int64_t pframe = granulepos - (iframe << theora_keyframe_granule_shift); - // check if maybe iframe is known from this page already - if (granulepos != -1 && iframe <= frame) - { - // optimisation, iframe is already known from this page - } else - { - // get previous page so we will get the iframe number - do { - ogg_get_prev_page(sw, serialno, &og); - } while (ogg_page_packets(&og) == 0); - - granulepos = ogg_page_granulepos(&og); - iframe = granulepos >> theora_keyframe_granule_shift; - //pframe = granulepos - (iframe << theora_keyframe_granule_shift); + granulepos &= ~((1<td, granulepos); + // iframe based on granulepos + if( frame < iframe || !ogg_get_page_of_frame(sw, serialno, &og, iframe) ) { + eprintf(_("FileOGG: seek to iframe failed\n")); + return 0; } - int64_t first_frame_on_page = theora_granule_frame(&tf->td, ogg_page_granulepos(&og)) - ogg_page_packets(&og) + 2; - if (!ogg_page_continued(&og)) - first_frame_on_page--; - if (first_frame_on_page <= iframe) - { - // optimisation, happens mainly in low-bitrate streams, it spares us one seek - } else - { - // get the page where keyframe starts - if (!ogg_get_page_of_frame(sw, serialno, &og, iframe)) - { - eprintf(_("FileOGG: Seeking to keyframe failed\n")); - return 0; - } + while( ogg_page_packets(&og) == 0 ) { + ogg_get_prev_page(sw, serialno, &og); } -// printf("looking for frame: %lli, last frame of the page: %lli, last keyframe: %lli\n", frame, pframe+iframe, iframe); + int64_t pageend_frame = theora_granule_frame(&tf->td, ogg_page_granulepos(&og)); + int64_t frames_on_page = ogg_page_packets(&og); + if( ogg_page_continued(&og) ) --frames_on_page; + // get frame before page with with iframe + int64_t page_frame = pageend_frame - frames_on_page; + if( page_frame < 0 ) page_frame = 0; +//printf("iframe %jd, page_frame %jd, frames_on_page %jd\n", iframe, page_frame, frames_on_page); ogg_stream_reset(&tf->to); ogg_stream_pagein(&tf->to, &og); - // Read until one frame before keyframe -// printf("c: %i\n", ogg_page_continued(&og)); - int numread = iframe - (theora_granule_frame(&tf->td, ogg_page_granulepos(&og)) - ogg_page_packets(&og)) - 1; - if (ogg_page_continued(&og)) - numread--; -// printf("numread: %i\n", numread); -// printf("FileOGG:: Proper position: %lli\n", theora_granule_frame(&tf->td, ogg_page_granulepos(&og)) + numread - ogg_page_packets(&og)); - while (numread > 0) - { - while (ogg_stream_packetpeek(&tf->to, NULL) != 1) - { - if (!ogg_get_next_page(sw, serialno, &og)) - { + + while( ++page_frame < iframe ) { + while( ogg_stream_packetpeek(&tf->to, NULL) != 1 ) { + if( !ogg_get_next_page(sw, serialno, &og) ) { eprintf(_("FileOGG: Cannot find next page while seeking\n")); return 0; } ogg_stream_pagein(&tf->to, &og); } ogg_stream_packetout(&tf->to, &op); - numread --; } - *keyframe_number = iframe; + + *position = iframe - 1; return 1; } @@ -1467,8 +1440,7 @@ int FileOGG::read_frame(VFrame *frame) } // printf("For frame: %lli, keyframe is: %lli\n", next_frame_position,ogg_frame_position); // skip frames must be > 0 here - decode_frames = next_frame_position - ogg_frame_position + 1; - ogg_frame_position --; // ogg_frame_position is at last decoded frame, so it will point right + decode_frames = next_frame_position - ogg_frame_position; if (decode_frames <= 0) { eprintf(_("FileOGG:: Error while seeking to keyframe," @@ -1483,6 +1455,7 @@ int FileOGG::read_frame(VFrame *frame) // printf("Frames to decode: %i\n", decode_frames); // THIS IS WHAT CAUSES SLOWNESS OF SEEKING, but we can do nothing about it. + int ret = -1; while (decode_frames > 0) { ogg_page og; @@ -1497,6 +1470,8 @@ int FileOGG::read_frame(VFrame *frame) ogg_stream_pagein(&tf->to, &og); } ogg_stream_packetout(&tf->to, &op); + if( theora_packet_isheader(&op) ) continue; +//printf("frame %jd, key %d\n", ogg_frame_position, theora_packet_iskeyframe(&op)); if (expect_keyframe && !theora_packet_iskeyframe(&op)) { eprintf(_("FileOGG: Expecting keyframe, but didn't get it\n")); @@ -1505,12 +1480,12 @@ int FileOGG::read_frame(VFrame *frame) expect_keyframe = 0; // decode - theora_decode_packetin(&tf->td, &op); - + ret = theora_decode_packetin(&tf->td, &op); +//if(ret < 0 )printf("ret = %d\n", ret); decode_frames --; ogg_frame_position ++; } - { + if( ret >= 0 ) { yuv_buffer yuv; int ret = theora_decode_YUVout (&tf->td, &yuv); if (ret) @@ -1524,15 +1499,9 @@ int FileOGG::read_frame(VFrame *frame) yuv.v += yuv.uv_stride * (yuv.uv_height - 1); yuv.y_stride = - yuv.y_stride; yuv.uv_stride = - yuv.uv_stride;*/ - VFrame *temp_frame = new VFrame(yuv.y, - -1, - 0, - yuv.u - yuv.y, - yuv.v - yuv.y, - - yuv.y_stride, - yuv.y_height, - BC_YUV420P, - - yuv.y_stride); + VFrame *temp_frame = new VFrame(yuv.y, -1, 0, + yuv.u - yuv.y, yuv.v - yuv.y, - yuv.y_stride, + yuv.y_height, BC_YUV420P, - yuv.y_stride); // copy into temp frame... BC_CModels::transfer(frame->get_rows(), @@ -1600,9 +1569,12 @@ int FileOGG::set_audio_position(int64_t x) int FileOGG::move_history(int from, int to, int len) { - for(int i = 0; i < asset->channels; i++) - memmove(pcm_history[i] + to, pcm_history[i] + from, sizeof(float) * len); + if( len > 0 ) { + for(int i = 0; i < asset->channels; i++) + memmove(pcm_history[i] + to, pcm_history[i] + from, sizeof(float) * len); + } history_start = history_start + from - to; + if( history_start < 0 ) history_start = 0; return 0; } @@ -1979,12 +1951,7 @@ int FileOGG::write_frames_theora(VFrame ***frames, int len, int e_o_s) if (!temp_frame) { - temp_frame = new VFrame (0, - -1, - tf->ti.width, - tf->ti.height, - BC_YUV420P, - -1); + temp_frame = new VFrame ( tf->ti.width, tf->ti.height, BC_YUV420P, 0); } VFrame *frame = frames[0][j]; int in_color_model = frame->get_color_model(); @@ -2036,8 +2003,7 @@ OGGConfigAudio::OGGConfigAudio(BC_WindowBase *parent_window, Asset *asset) : BC_Window(_(PROGRAM_NAME ": Audio Compression"), parent_window->get_abs_cursor_x(1), parent_window->get_abs_cursor_y(1), - 350, - 250) + 350, 250) { this->parent_window = parent_window; this->asset = asset; @@ -2163,8 +2129,7 @@ OGGConfigVideo::OGGConfigVideo(BC_WindowBase *parent_window, Asset *asset) : BC_Window(_(PROGRAM_NAME ": Video Compression"), parent_window->get_abs_cursor_x(1), parent_window->get_abs_cursor_y(1), - 450, - 220) + 450, 220) { this->parent_window = parent_window; this->asset = asset; @@ -2189,18 +2154,10 @@ void OGGConfigVideo::create_objects() y += 30; add_subwindow(new BC_Title(x, y, _("Quality:"))); - add_subwindow(new BC_ISlider(x + 80, - y, - 0, - 200, - 200, - 0, - 63, - asset->theora_quality, - 0, - 0, - &asset->theora_quality)); - + add_subwindow(new BC_ISlider(x + 80, y, 0, + 200, 200, 0, 63, + asset->theora_quality, 0, + 0, &asset->theora_quality)); add_subwindow(fixed_quality = new OGGTheoraFixedQuality(x2, y, this)); y += 30; @@ -2230,8 +2187,6 @@ void OGGConfigVideo::create_objects() } - - int OGGConfigVideo::close_event() { set_done(0); @@ -2354,7 +2309,7 @@ PackagingEngineOGG::~PackagingEngineOGG() delete [] packages; } if (default_asset) - delete default_asset; + default_asset->remove_user(); } @@ -2362,8 +2317,8 @@ PackagingEngineOGG::~PackagingEngineOGG() int PackagingEngineOGG::create_packages_single_farm( EDL *edl, Preferences *preferences, - Asset *default_asset, - double total_start, + Asset *default_asset, + double total_start, double total_end) { this->total_start = total_start; @@ -2372,7 +2327,7 @@ int PackagingEngineOGG::create_packages_single_farm( this->preferences = preferences; -// We make A COPY of the asset, because we set audio_data = 0 on local asset which is the same copy as default_asset... +// We make A COPY of the asset, because we set audio_data = 0 on local asset which is the same copy as default_asset... // Should be taken care of somewhere else actually this->default_asset = new Asset(*default_asset); @@ -2399,10 +2354,12 @@ int PackagingEngineOGG::create_packages_single_farm( if (default_asset->audio_data) { packages[local_current_package] = new RenderPackage; - sprintf(packages[current_package]->path, "%s.audio", default_asset->path); + snprintf(packages[current_package]->path, + sizeof(packages[current_package]->path), + "%s.audio", default_asset->path); local_current_package++; } - + if (default_asset->video_data) { video_package_len = (total_len) / preferences->renderfarm_job_count; @@ -2410,17 +2367,17 @@ int PackagingEngineOGG::create_packages_single_farm( int number_start; // Character in the filename path at which the number begins int total_digits; // Total number of digits including padding the user specified. - Render::get_starting_number(default_asset->path, + Render::get_starting_number(default_asset->path, current_number, - number_start, + number_start, total_digits, 3); for(int i = 0; i < preferences->renderfarm_job_count; i++) { RenderPackage *package = packages[local_current_package] = new RenderPackage; - Render::create_filename(package->path, - default_asset->path, + Render::create_filename(package->path, + default_asset->path, current_number, total_digits, number_start); @@ -2431,7 +2388,7 @@ int PackagingEngineOGG::create_packages_single_farm( return 0; } -RenderPackage* PackagingEngineOGG::get_package_single_farm(double frames_per_second, +RenderPackage* PackagingEngineOGG::get_package_single_farm(double frames_per_second, int client_number, int use_local_rate) { @@ -2459,13 +2416,13 @@ RenderPackage* PackagingEngineOGG::get_package_single_farm(double frames_per_sec result->audio_start = audio_position; result->video_start = video_position; - result->audio_end = audio_position + + result->audio_end = audio_position + Units::round(video_package_len * default_asset->sample_rate); - result->video_end = video_position + + result->video_end = video_position + Units::round(video_package_len * default_asset->frame_rate); // Last package... take it all! - if (current_package == total_packages -1 ) + if (current_package == total_packages -1 ) { result->audio_end = audio_end; result->video_end = video_end; @@ -2475,7 +2432,7 @@ RenderPackage* PackagingEngineOGG::get_package_single_farm(double frames_per_sec video_position = result->video_end; } - + current_package ++; return result; @@ -2494,9 +2451,9 @@ void PackagingEngineOGG::get_package_paths(ArrayList *path_list) int64_t PackagingEngineOGG::get_progress_max() { - return Units::to_int64(default_asset->sample_rate * + return Units::to_int64(default_asset->sample_rate * (total_end - total_start)) * 2+ - Units::to_int64(preferences->render_preroll * + Units::to_int64(preferences->render_preroll * total_packages * default_asset->sample_rate); } @@ -2505,7 +2462,7 @@ int PackagingEngineOGG::packages_are_done() { -// Mux audio and video into one file +// Mux audio and video into one file // First fix our asset... have to workaround the bug of corruption of local asset // Render::check_asset(edl, *default_asset); @@ -2514,11 +2471,12 @@ int PackagingEngineOGG::packages_are_done() File *audio_file_gen = 0, *video_file_gen = 0; FileOGG *video_file = 0, *audio_file = 0; ogg_stream_state audio_in_stream, video_in_stream; - + int local_current_package = 0; if (default_asset->audio_data) { audio_asset = new Asset(packages[local_current_package]->path); + audio_asset->format = FILE_OGG; local_current_package++; audio_file_gen = new File(); @@ -2531,6 +2489,7 @@ int PackagingEngineOGG::packages_are_done() if (default_asset->video_data) { video_asset = new Asset(packages[local_current_package]->path); + video_asset->format = FILE_OGG; local_current_package++; video_file_gen = new File(); @@ -2570,8 +2529,9 @@ int PackagingEngineOGG::packages_are_done() ogg_stream_clear(&video_in_stream); video_file_gen->close_file(); delete video_file_gen; - delete video_asset; + if( video_asset ) video_asset->remove_user(); video_asset = new Asset(packages[local_current_package]->path); + video_asset->format = FILE_OGG; local_current_package++; video_file_gen = new File(); @@ -2600,20 +2560,20 @@ int PackagingEngineOGG::packages_are_done() int64_t granulepos = op.granulepos; if (granulepos != -1) { - // Fix granulepos! + // Fix granulepos! int64_t rel_iframe = granulepos >> video_file->theora_keyframe_granule_shift; int64_t rel_pframe = granulepos - (rel_iframe << video_file->theora_keyframe_granule_shift); int64_t rel_current_frame = rel_iframe + rel_pframe; current_frame = frame_offset + rel_current_frame; int64_t abs_iframe = current_frame - rel_pframe; - + op.granulepos = (abs_iframe << video_file->theora_keyframe_granule_shift) + rel_pframe; - -// printf("iframe: %i, pframe: %i, granulepos: %i, op.packetno %lli, abs_iframe: %i\n", rel_iframe, rel_pframe, granulepos, op.packetno, abs_iframe); - + +// printf("iframe: %i, pframe: %i, granulepos: %i, op.packetno %lli, abs_iframe: %i\n", rel_iframe, rel_pframe, granulepos, op.packetno, abs_iframe); + } ogg_stream_packetin (&output_file->tf->to, &op); - output_file->tf->v_pkg++; + output_file->tf->v_pkg++; } } if (audio_ready) @@ -2632,42 +2592,44 @@ int PackagingEngineOGG::packages_are_done() ogg_stream_packetout(&audio_in_stream, &op); ogg_stream_packetin (&output_file->tf->vo, &op); audio_packetno++; - output_file->tf->a_pkg++; + output_file->tf->a_pkg++; } } - + output_file->flush_ogg(0); - - + + } - -// flush_ogg(1) is called on file closing time... + +// flush_ogg(1) is called on file closing time... // output_file->flush_ogg(1); // Just prevent thet write_samples and write_frames are called output_file->final_write = 0; - + if (default_asset->audio_data) { ogg_stream_clear(&audio_in_stream); audio_file_gen->close_file(); delete audio_file_gen; - delete audio_asset; + if( audio_asset ) + audio_asset->remove_user(); } if (default_asset->video_data) { ogg_stream_clear(&video_in_stream); video_file_gen->close_file(); delete video_file_gen; - delete video_asset; + if( video_asset ) + video_asset->remove_user(); } output_file_gen->close_file(); delete output_file_gen; -// Now delete the temp files - for(int i = 0; i < total_packages; i++) - unlink(packages[i]->path); +// don't delete the temp files, for now +// for(int i = 0; i < total_packages; i++) +// unlink(packages[i]->path); return 0; }