}
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)
{
}
else if (ret < 0)
{
- eprintf("FileOGG: Taking page out on nonsynced stream!\n");
+ eprintf(_("FileOGG: Taking page out on nonsynced stream!\n"));
return ret;
} else
if((stream = fopen(asset->path, "w+b")) == 0)
{
- eprintf("Error while opening \"%s\" for writing. %m\n", asset->path);
+ eprintf(_("Error while opening \"%s\" for writing. %m\n"), asset->path);
return 1;
}
tf->ti.height = ((asset->height + 15) >>4)<<4; // round up to the nearest multiple of 16
if (tf->ti.width != tf->ti.frame_width || tf->ti.height != tf->ti.frame_height)
{
- eprintf("WARNING: Encoding theora when width or height are not dividable by 16 is suboptimal\n");
+ eprintf(_("WARNING: Encoding theora when width or height are not dividable by 16 is suboptimal\n"));
}
tf->ti.offset_x = 0;
if (theora_encode_init (&tf->td, &tf->ti))
{
- eprintf("(FileOGG:file_open) initialization of theora codec failed\n");
+ eprintf(_("(FileOGG:file_open) initialization of theora codec failed\n"));
}
}
/* init theora done */
if((stream = fopen(asset->path, "rb")) == 0)
{
- eprintf("Error while opening %s for reading. %m\n", asset->path);
+ eprintf(_("Error while opening %s for reading. %m\n"), asset->path);
return 1;
}
if(tf->ti.width!=tf->ti.frame_width || tf->ti.height!=tf->ti.frame_height)
{
- eprintf("Frame content is %dx%d with offset (%d,%d), We do not support this yet. You will get black border.\n",
+ eprintf(_("Frame content is %dx%d with offset (%d,%d), We do not support this yet. You will get black border.\n"),
tf->ti.frame_width, tf->ti.frame_height, tf->ti.offset_x, tf->ti.offset_y);
}
tf->videosync = new sync_window_t;
asset->frame_rate = fps;
// All theora material is noninterlaced by definition
if(!asset->interlace_mode)
- asset->interlace_mode = BC_ILACE_MODE_NOTINTERLACED;
+ asset->interlace_mode = ILACE_MODE_NOTINTERLACED;
/* ogg_get_page_of_frame(tf->videosync, tf->to.serialno, &og, 0 +start_frame);
ogg_get_page_of_frame(tf->videosync, tf->to.serialno, &og, 1 +start_frame);
{
vorbis_synthesis_init(&tf->vd, &tf->vi);
vorbis_block_init(&tf->vd, &tf->vb);
-/* eprintf("FileOGG: Ogg logical stream %x is Vorbis %d channel %d Hz audio.\n",
+/* eprintf(_("FileOGG: Ogg logical stream %x is Vorbis %d channel %d Hz audio.\n"),
(unsigned int)tf->vo.serialno, tf->vi.channels, (int)tf->vi.rate);
*/
/* init audio_sync structure */
{
if (previous_comming_sample > sample)
{
- eprintf("Ogg decoding error while seeking sample\n");
+ eprintf(_("Ogg decoding error while seeking sample\n"));
}
vorbis_synthesis_read(&tf->vd, (sample - previous_comming_sample));
// printf("WE GOT IT, samples already decoded: %jd\n", vorbis_synthesis_pcmout(&tf->vd,NULL));
}
-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<<theora_keyframe_granule_shift)-1);
+ int64_t iframe = theora_granule_frame(&tf->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;
}
}
// 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,"
// 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;
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"));
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)
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(),
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;
}
if(len > HISTORY_MAX)
{
- eprintf("max samples=%d\n", HISTORY_MAX);
+ eprintf(_("max samples=%d\n"), HISTORY_MAX);
return 1;
}
ogg_sample_position = hole_absstart;
if (!ogg_seek_to_sample(tf->audiosync, tf->vo.serialno, ogg_sample_position))
{
- eprintf("Error while seeking to sample\n");
+ eprintf(_("Error while seeking to sample\n"));
return 1;
}
}
ret = fwrite(tf->apage, 1, tf->apage_len, stream);
if(ret < tf->apage_len)
{
- eprintf("error writing audio page\n");
+ eprintf(_("error writing audio page\n"));
}
tf->apage_valid = 0;
tf->a_pkg -= ogg_page_packets((ogg_page *)&tf->apage);
ret = fwrite(tf->vpage, 1, tf->vpage_len, stream);
if(ret < tf->vpage_len)
{
- eprintf("error writing video page\n");
+ eprintf(_("error writing video page\n"));
}
tf->vpage_valid = 0;
tf->v_pkg -= ogg_page_packets((ogg_page *)&tf->vpage);
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();
: 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;
: 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;
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;
}
-
-
int OGGConfigVideo::close_event()
{
set_done(0);
delete [] packages;
}
if (default_asset)
- delete default_asset;
+ default_asset->remove_user();
}
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;
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);
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;
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);
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)
{
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;
video_position = result->video_end;
}
-
+
current_package ++;
return result;
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);
}
{
-// 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);
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();
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();
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();
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)
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;
}