Main Page | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Class Members | File Members

filedv.C

Go to the documentation of this file.
00001 #ifdef HAVE_FIREWIRE
00002 
00003 #include "asset.h"
00004 #include "bcsignals.h"
00005 #include "byteorder.h"
00006 #include "dv1394.h"
00007 #include "edit.h"
00008 #include "file.h"
00009 #include "filedv.h"
00010 #include "guicast.h"
00011 #include "interlacemodes.h"
00012 #include "language.h"
00013 #include "mwindow.inc"
00014 #include "quicktime.h"
00015 #include "vframe.h"
00016 #include "videodevice.inc"
00017 #include "cmodel_permutation.h"
00018 
00019 #include <sys/types.h>
00020 #include <sys/stat.h>
00021 #include <fcntl.h>
00022 #include <unistd.h>
00023 #include <string.h>
00024 #include <errno.h>
00025 
00026 FileDV::FileDV(Asset *asset, File *file)
00027  : FileBase(asset, file)
00028 {
00029 #ifdef DV_USE_FFMPEG
00030         avcodec_init();
00031         avcodec_register_all();
00032         codec = 0;
00033         context = 0;
00034         picture = 0;
00035 #endif // DV_USE_FFMPEG
00036 
00037         decoder = 0;
00038         encoder = 0;
00039         audio_buffer = 0;
00040         input = 0;
00041         output = 0;
00042         if(asset->format == FILE_UNKNOWN)
00043                 asset->format = FILE_RAWDV;
00044         asset->byte_order = 0;
00045         isPAL = 0;
00046         reset_parameters();
00047 }
00048 
00049 FileDV::~FileDV()
00050 {
00051         int i = 0;
00052         if(stream) close_file();
00053 
00054 #ifdef DV_USE_FFMPEG
00055         if(context)
00056         {
00057                 avcodec_close(context);
00058                 free(context);
00059         }
00060         if(picture) free(picture);
00061 #endif // DV_USE_FFMPEG
00062 
00063         if(decoder) dv_decoder_free(decoder);
00064         if(encoder) dv_encoder_free(encoder);
00065         if(audio_buffer)
00066         {
00067                 for(i = 0; i < asset->channels; i++)
00068                         free(audio_buffer[i]);
00069                 free(audio_buffer);
00070         }
00071         delete[] output;
00072         delete[] input;
00073 }
00074 
00075 void FileDV::get_parameters(BC_WindowBase *parent_window,
00076         Asset *asset,
00077         BC_WindowBase* &format_window,
00078         int audio_options,
00079         int video_options)
00080 {
00081         if(audio_options)
00082         {
00083                 DVConfigAudio *window = new DVConfigAudio(parent_window, asset);
00084                 format_window = window;
00085                 window->create_objects();
00086                 window->run_window();
00087                 delete window;
00088         }
00089         else
00090         if(video_options)
00091         {
00092                 DVConfigVideo *window = new DVConfigVideo(parent_window, asset);
00093                 format_window = window;
00094                 window->create_objects();
00095                 window->run_window();
00096                 delete window;
00097         }
00098 
00099 }
00100 
00101 int FileDV::reset_parameters_derived()
00102 {
00103         int i = 0;
00104 
00105 #ifdef DV_USE_FFMPEG
00106         if(codec)
00107         {
00108                 avcodec_close(context);
00109                 free(context);
00110                 context = 0;
00111                 codec = 0;
00112         }
00113         if(picture) free(picture);
00114         picture = 0;
00115 #endif // DV_USE_FFMPEG
00116 
00117         if(decoder) dv_decoder_free(decoder);
00118         if(encoder) dv_encoder_free(encoder);
00119 
00120 TRACE("FileDV::reset_parameters_derived 10")
00121 
00122 #ifdef DV_USE_FFMPEG
00123         codec = avcodec_find_decoder(CODEC_ID_DVVIDEO);
00124         context = avcodec_alloc_context();
00125         avcodec_open(context, codec);
00126 #endif // DV_USE_FFMPEG
00127 
00128         decoder = dv_decoder_new(0,0,0);
00129         decoder->quality = DV_QUALITY_BEST;
00130         encoder = dv_encoder_new(0,0,0);
00131         encoder->vlc_encode_passes = 3;
00132         encoder->static_qno = 0;
00133         encoder->force_dct = DV_DCT_AUTO;
00134         
00135 TRACE("FileDV::reset_parameters_derived: 20")
00136         
00137         if(audio_buffer)
00138         {
00139                 for(i = 0; i < asset->channels; i++)
00140                 {
00141                         if(audio_buffer[i]) free(audio_buffer[i]);
00142                 }
00143                 free(audio_buffer);
00144         }
00145 
00146 TRACE("FileDV::reset_parameters_derived: 30")
00147         
00148         audio_buffer = 0;
00149         samples_in_buffer = 0;
00150         for(i = 0; i < 4; i++) // max 4 channels in dv
00151                 samples_offset[i] = 0;
00152 
00153         frames_written = 0;
00154 
00155         stream = 0;
00156         audio_position = 0;
00157         video_position = 0;
00158 // output_size gets set in open_file, once we know if the frames are PAL or NTSC
00159 // output and input are allocated at the same point.
00160         output_size = 0;
00161         delete[] output;
00162         delete[] input;
00163         audio_offset = 0;
00164         video_offset = 0;
00165         current_frame = asset->tcstart;
00166         
00167 UNTRACE
00168 
00169 }
00170 
00171 int FileDV::open_file(int rd, int wr)
00172 {
00173 
00174 TRACE("FileDV::open_file 10")
00175 
00176         if(wr)
00177         {
00178 
00179 TRACE("FileDV::open_file 20")
00180 
00181                 if((stream = fopen(asset->path, "w+b")) == 0)
00182                 {
00183                         perror(_("FileDV::open_file rdwr"));
00184                         return 1;
00185                 }
00186 
00187                 isPAL = (asset->height == 576 ? 1 : 0);
00188                 encoder->isPAL = isPAL;
00189                 output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
00190         }
00191         else
00192         {
00193                 unsigned char *temp;
00194 
00195 TRACE("FileDV::open_file 30")
00196 
00197                 struct stat *info;
00198 
00199 TRACE("FileDV::open_file 40")
00200 
00201                 if((stream = fopen(asset->path, "rb")) == 0)
00202                 {
00203                         perror(_("FileDV::open_file rd"));
00204                         return 1;
00205                 }
00206 
00207                 // temp storage to find out the correct info from the stream.
00208                 temp = new unsigned char[DV1394_PAL_FRAME_SIZE + 8];
00209                 memset(temp, 0, DV1394_PAL_FRAME_SIZE + 8);
00210 
00211                 // need file size info to get length.
00212                 info = (struct stat*) malloc(sizeof(struct stat));
00213                 stat(asset->path, info);
00214                 
00215 TRACE("FileDV::open_file 50")
00216 
00217                 // read the first frame so we can get the stream info from it
00218                 // by reading the greatest possible frame size, we ensure we get all the
00219                 // data. libdv will determine if it's PAL or NTSC, and input and output
00220                 // buffers get allocated accordingly.
00221                 fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
00222 
00223 TRACE("FileDV::open_file 60")
00224 
00225                 if(dv_parse_header(decoder, temp) > -1 )
00226                 {
00227                         char tc[12];
00228                         
00229                         // define video params first -- we need to find out output_size
00230                         // always have video
00231                         asset->video_data = 1;
00232                         asset->layers = 1;
00233                         asset->aspect_ratio = (double) 4 / 3;
00234                         asset->width = decoder->width;
00235                         asset->height = decoder->height;
00236                         asset->interlace_mode = BC_ILACE_MODE_BOTTOM_FIRST;
00237                         if(asset->height == 576)
00238                         {
00239                                 isPAL = 1;
00240                                 encoder->isPAL = 1;
00241                         }
00242                         output_size = (isPAL ? DV1394_PAL_FRAME_SIZE : DV1394_NTSC_FRAME_SIZE);
00243                         asset->video_length = info->st_size / output_size;
00244                         if(!asset->frame_rate)
00245                                 asset->frame_rate = (isPAL ? 25 : 29.97);
00246                         strncpy(asset->vcodec, "dvc ", 4);
00247 
00248                         // see if there are any audio tracks
00249                         asset->channels = decoder->audio->num_channels;
00250                         if(asset->channels > 0)
00251                         {
00252                                 asset->audio_data = 1;
00253                                 asset->sample_rate = decoder->audio->frequency;
00254                                 asset->bits = decoder->audio->quantization;
00255                                 asset->audio_length = info->st_size * decoder->audio->samples_this_frame / output_size;
00256                                 strncpy(asset->acodec, "dvc ", 4);
00257                         }
00258                         else
00259                                 asset->audio_data = 0;
00260 
00261                         // Set start timecode
00262                         dv_parse_packs(decoder, temp);
00263                         dv_get_timestamp(decoder, tc);
00264                         asset->set_timecode(tc, TC_DROPFRAME, 0);
00265 
00266                         // Get the last frame's timecode
00267                         set_video_position(asset->video_length);
00268                         fread(temp, DV1394_PAL_FRAME_SIZE, 1, stream);
00269                         dv_parse_header(decoder, temp);
00270                         dv_parse_packs(decoder, temp);
00271                         dv_get_timestamp(decoder, tc);
00272                         
00273                         asset->set_timecode(tc, TC_DROPFRAME, 1);
00274                 }
00275                 else
00276                 {
00277                         asset->audio_data = 0;
00278                         asset->video_data = 0;
00279                 }
00280 
00281                 fseek(stream, 0, SEEK_SET);
00282 TRACE("FileDV::open_file 80")
00283 
00284                 delete[] temp;
00285                 free(info);
00286         }
00287         delete[] input;
00288         delete[] output;
00289 
00291         input = new unsigned char[output_size + 8];
00292         output = new unsigned char[output_size + 8];
00293         memset(input, 0, output_size + 8);
00294         memset(output, 0, output_size + 8);
00295                         
00296 UNTRACE
00297         return 0;
00298 }
00299 
00300 int FileDV::check_sig(Asset *asset)
00301 {
00302         unsigned char temp[3];
00303         FILE *t_stream = fopen(asset->path, "rb");
00304 
00305         fread(&temp, 3, 1, t_stream);
00306 
00307         fclose(t_stream);
00308         
00309         if(temp[0] == 0x1f &&
00310                         temp[1] == 0x07 &&
00311                         temp[2] == 0x00)
00312                 return 1;
00313 
00314         return 0;
00315 }
00316 
00317 int FileDV::close_file()
00318 {
00319         fclose(stream);
00320         stream = 0;
00321 }
00322 
00323 int FileDV::close_file_derived()
00324 {
00325 //printf("FileDV::close_file_derived(): 1\n");
00326         fclose(stream);
00327         stream = 0;
00328 }
00329 
00330 int64_t FileDV::get_video_position()
00331 {
00332         return video_offset / output_size;
00333 }
00334 
00335 int64_t FileDV::get_audio_position()
00336 {
00337         return audio_position;
00338 }
00339 
00340 int FileDV::set_video_position(int64_t x)
00341 {
00342         if(!stream) return 1;
00343         if(x >= 0 && x < asset->video_length)
00344         {
00345                 video_offset = x * output_size;
00346                 return 0;
00347         }
00348         else
00349                 return 1;
00350 }
00351 
00352 int FileDV::set_audio_position(int64_t x)
00353 {
00354         int i = 0;
00355         if(!stream) return 1;
00356         if(x >= 0 && x < asset->audio_length)
00357         {
00358                 audio_position = x;
00359                 audio_offset = output_size * (int64_t) (x / (asset->sample_rate / asset->frame_rate));
00360                 for(i = 0; i < 4; i++)
00361                 {
00362                         samples_offset[i] = audio_position - (int) (audio_offset / output_size / asset->frame_rate * asset->sample_rate);
00363                 }
00364                 return 0;
00365         }
00366         else
00367                 return 1;
00368 }
00369 
00370 int FileDV::write_samples(double **buffer, int64_t len)
00371 {
00372         int frame_num = (int) (audio_offset / output_size);
00373         // How many samples do we write this frame?
00374         int samples = calculate_samples(frame_num);
00375         int samples_written = 0;
00376         int i, j, k = 0;
00377         unsigned char *temp_data = (unsigned char *) calloc(sizeof(unsigned char*), output_size);
00378         int16_t *temp_buffers[asset->channels];
00379 
00380 TRACE("FileDV::write_samples 10")
00381 
00382         if(!audio_buffer)
00383         {
00384                 audio_buffer = (int16_t **) calloc(sizeof(int16_t*), asset->channels);
00385 
00386                 // TODO: should reallocate if len > asset->sample_rate * 2, or
00387                 // len > asset->sample_rate + samples_in_buffer
00388                 
00389                 // allocate enough so that we can write two seconds worth of frames (we
00390                 // usually receive one second of frames to write, and we need
00391                 // overflow if the frames aren't already written
00392                 for(i = 0; i < asset->channels; i++)
00393                 {
00394                         audio_buffer[i] = (int16_t *) calloc(sizeof(int16_t), asset->sample_rate * 2);
00395                 }
00396         }
00397 
00398 TRACE("FileDV::write_samples 20")
00399 
00400         for(i = 0; i < asset->channels; i++)
00401         {
00402                 temp_buffers[i] = audio_buffer[i];
00403                 // Need case handling for bitsize ?
00404 
00405 TRACE("FileDV::write_samples 22")
00406 
00407                 for(j = 0; j < len; j++)
00408                 {
00409 
00410 TRACE("FileDV::write_samples 24")
00411 
00412                         if(samples_in_buffer > 0)
00413                                 temp_buffers[i][j + samples_in_buffer - 1] = (int16_t) (buffer[i][j] * 32767);
00414                         else
00415                                 temp_buffers[i][j] = (int16_t) (buffer[i][j] * 32767);
00416                 }
00417         }
00418 
00419         samples_in_buffer += len;
00420 
00421 TRACE("FileDV::write_samples 30")
00422 
00423 // We can only write the number of frames that write_frames has written
00424 // since our last audio write, and we can't write more than the
00425 // samples we have available from the last write and this one
00426         for(i = 0; i < frames_written && samples_written + samples <= samples_in_buffer; i++)
00427         {
00428                 // Position ourselves to where we last wrote audio
00429                 fseek(stream, audio_offset, SEEK_SET);
00430 
00431                 // Read the frame in, add the audio, write it back out to the same
00432                 // location and adjust audio_offset to the new file position
00433                 if(fread(temp_data, output_size, 1, stream) < 1) break;
00434                 encoder->samples_this_frame = samples;
00435                 dv_encode_full_audio(encoder, temp_buffers, asset->channels,
00436                         asset->sample_rate, temp_data);
00437                 fseek(stream, audio_offset, SEEK_SET);
00438                 fwrite(temp_data, output_size, 1, stream);
00439                 audio_offset += output_size;
00440 
00441 TRACE("FileDV::write_samples 50")
00442 
00443                 // Get the next set of samples for the next frame
00444                 for(j = 0; j < asset->channels; j++)
00445                         temp_buffers[j] += samples;
00446 
00447 TRACE("FileDV::write_samples 60")
00448 
00449                 // increase the number of samples written so we can determine how many
00450                 // samples to leave in the buffer for the next write
00451                 samples_written += samples;
00452                 frame_num++;
00453                 samples = calculate_samples(frame_num);
00454         }
00455 
00456         // Get number of frames we didn't write to
00457         frames_written -= i;
00458 
00459         if(samples_written < samples_in_buffer)
00460         {
00461         // move the rest of the buffer to the front
00462 
00463 TRACE("FileDV::write_samples 70")
00464 
00465                 samples_in_buffer -= samples_written;
00466                 for(i = 0; i < asset->channels; i++)
00467                 {
00468                         memmove(audio_buffer[i], temp_buffers[i], asset->sample_rate * 2 - samples_written);
00469                 }
00470         }
00471         else
00472         {
00473                 samples_in_buffer = 0;
00474         }
00475 
00476 TRACE("FileDV::write_samples 80")
00477 
00478         if(temp_data) free(temp_data);
00479 
00480 UNTRACE
00481 
00482         return 0;
00483 }
00484 
00485 int FileDV::write_frames(VFrame ***frames, int len)
00486 {
00487         int i, j, result = 0;
00488 
00489         if(!stream) return 0;
00490 
00491         for(j = 0; j < len && !result; j++)
00492         {
00493                 VFrame *temp_frame = new VFrame(frames[0][j]->get_data(),
00494                         asset->width,
00495                         asset->height,
00496                         frames[0][j]->get_color_model(),
00497                         frames[0][j]->get_bytes_per_line());
00498 
00499                         unsigned char *frame_buf = (unsigned char *)malloc(asset->height * asset->width * 2);
00500                         unsigned char **cmodel_buf = (unsigned char **)malloc(sizeof(unsigned char*) * asset->height);
00501 
00502                         for(i = 0; i < asset->height; i++)
00503                                 cmodel_buf[i] = frame_buf + 720 * 2 * i;
00504 
00505 //printf("FileDV::write_frames: color_model %i\n", temp_frame->get_color_model());
00506                         switch(temp_frame->get_color_model())
00507                         {
00508                                 case BC_COMPRESSED:
00509                                         memcpy(output, temp_frame->get_data(), output_size);
00510                                         break;
00511                                 case BC_YUV422:
00512 //printf("FileDV::write_frames: 4\n");
00513                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
00514                                                 e_dv_color_yuv, output);
00515                                         break;
00516                                 case BC_RGB888:
00517 //printf("FileDV::write_frames: 5\n");
00518                                         dv_encode_full_frame(encoder, temp_frame->get_rows(),
00519                                                 e_dv_color_rgb, output);
00520                                         break;
00521                                 default:
00522 //printf("FileDV::write_frames: 6\n");
00523                                         unsigned char **row_pointers = temp_frame->get_rows();
00524                                         cmodel_transfer(cmodel_buf,
00525                                                 row_pointers,
00526                                                 cmodel_buf[0],
00527                                                 cmodel_buf[1],
00528                                                 cmodel_buf[2],
00529                                                 row_pointers[0],
00530                                                 row_pointers[1],
00531                                                 row_pointers[2],
00532                                                 0,
00533                                                 0,
00534                                                 asset->width,
00535                                                 asset->height,
00536                                                 0,
00537                                                 0,
00538                                                 asset->width,
00539                                                 asset->height,
00540                                                 temp_frame->get_color_model(),
00541                                                 BC_YUV422,
00542                                                 0,
00543                                                 asset->width,
00544                                                 asset->width);
00545 
00546                                         dv_encode_full_frame(encoder, cmodel_buf,
00547                                                 e_dv_color_yuv, output);
00548                                         break;
00549                         }
00550 //printf("FileDV::write_frames: 7\n");
00551 
00552                 fseek(stream, video_offset, SEEK_SET);
00553                 fwrite(output, output_size, 1, stream);
00554                 video_offset += output_size;
00555                 frames_written++;
00556 
00557                 free(cmodel_buf);
00558                 free(frame_buf);
00559                 delete temp_frame;
00560                 }
00561                 
00562         return 0;
00563 }
00564 
00565 int FileDV::read_compressed_frame(VFrame *buffer)
00566 {
00567         int64_t result;
00568         if(!stream) return 0;
00569 
00570         fseek(stream, video_offset, SEEK_SET);
00571         fread(buffer->get_data(), output_size, 1, stream);
00572         video_offset += output_size;
00573 
00574         buffer->set_compressed_size(result);
00575         result = !result;
00576         
00577         return result;
00578 }
00579 
00580 int FileDV::write_compressed_frame(VFrame *buffer)
00581 {
00582         int result = 0;
00583         if(!stream) return 0;
00584 
00585         fseek(stream, video_offset, SEEK_SET);
00586         fwrite(buffer->get_data(), buffer->get_compressed_size(), 1, stream);
00587         video_offset += output_size;
00588 
00589         frames_written++;
00590 
00591         return result;
00592 }
00593 
00594 int64_t FileDV::compressed_frame_size()
00595 {
00596         if(!stream) return 0;
00597         return output_size;
00598 }
00599 
00600 int FileDV::read_samples(double *buffer, int64_t len)
00601 {
00602         int frameno = audio_offset / output_size;
00603         int16_t **outbuf = 0;
00604         int16_t **temp_buffer = 0;
00605         int i, j = 0;
00606         int channel = file->current_channel;
00607         int offset = samples_offset[channel];
00608 
00609 TRACE("FileDV::read_samples 10")
00610 
00611         outbuf = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
00612         temp_buffer = (int16_t **) calloc(sizeof(int16_t *), asset->channels);
00613 
00614 TRACE("FileDV::read_samples 20")
00615 
00616         for(i = 0; i < asset->channels; i++)
00617         {
00618         // need a bit extra, since chances are len is not a multiple of the
00619         // samples per frame.
00620 
00621 TRACE("FileDV::read_samples 30")
00622 
00623                 outbuf[i] = (int16_t *) calloc(sizeof(int16_t), len + 2 * DV_AUDIO_MAX_SAMPLES);
00624                 temp_buffer[i] = outbuf[i];
00625         }
00626 
00627 TRACE("FileDV::read_samples 40")
00628 
00629         // set file position
00630         fseek(stream, audio_offset, SEEK_SET);
00631 
00632         // get audio data and put it in buffer
00633         for(i = 0; i < len + calculate_samples(frameno); i += calculate_samples(frameno))
00634         {
00635 
00636 TRACE("FileDV::read_samples 50")
00637 
00638                 fread(input, output_size, 1, stream);
00639                 audio_offset += output_size;
00640                 dv_decode_full_audio(decoder, input, temp_buffer);
00641 
00642 TRACE("FileDV::read_samples 60")
00643 
00644                 for(j = 0; j < asset->channels; j++)
00645                         temp_buffer[j] += calculate_samples(frameno);
00646 
00647                 frameno++;
00648         }
00649 
00650 TRACE("FileDV::read_samples 70")
00651 
00652         for(i = 0; i < len; i++)
00653                 buffer[i] = (double) outbuf[channel][i + offset] / 32767;
00654 
00655 TRACE("FileDV::read_samples 80")
00656 
00657         samples_offset[channel] = (len + offset) % calculate_samples(frameno);
00658 
00659 TRACE("FileDV::read_samples 90")
00660 
00661 // we do this to keep everything in sync. When > 1 channel is being
00662 // played, our set_audio_position gets overriden every second time,
00663 // which is a Good Thing (tm) since it would otherwise be wrong.
00664         set_audio_position(audio_position + len);
00665 
00666 TRACE("FileDV::read_samples 100")
00667 
00668         free(temp_buffer);
00669 
00670 TRACE("FileDV::read_samples 105")
00671 
00672         for(i = 0; i < asset->channels; i++)
00673                 free(outbuf[i]);
00674 
00675 TRACE("FileDV::read_samples 110")
00676 
00677         free(outbuf);
00678 
00679 UNTRACE
00680 
00681         return 0;
00682 }
00683 
00684 int FileDV::read_frame(VFrame *frame)
00685 {
00686         if(!stream) return 1;
00687         int i, result = 0;
00688         int pitches[3] = {720 * 2, 0, 0};
00689 
00690 TRACE("FileDV::read_frame 1")
00691 
00692         unsigned char **row_pointers = frame->get_rows();
00693 
00694         unsigned char *temp_data = (unsigned char *) malloc(asset->height * asset->width * 2);
00695         unsigned char **temp_pointers = (unsigned char **)malloc(sizeof(unsigned char *) * asset->height);
00696 
00697 TRACE("FileDV::read_frame 10")
00698 
00699         for(i = 0; i < asset->height; i++)
00700                 temp_pointers[i] = temp_data + asset->width * 2 * i;
00701 
00702         // Seek to video position
00703         if(fseek(stream, video_offset, SEEK_SET) < 0) return 1;
00704         fread(input, output_size, 1, stream);
00705         video_offset += output_size;
00706         
00707 
00708 TRACE("FileDV::read_frame 20")
00709 
00710         switch(frame->get_color_model())
00711         {
00712                 case BC_COMPRESSED:
00713 
00714 TRACE("FileDV::read_frame 30")
00715 
00716                         frame->allocate_compressed_data(output_size);
00717                         frame->set_compressed_size(output_size);
00718                         memcpy(frame->get_data(), input, output_size);
00719                         break;
00720 #ifndef DV_USE_FFMPEG
00721 
00722                 case BC_RGB888:
00723 
00724 TRACE("FileDV::read_frame 40")
00725 
00726                         pitches[0] = 720 * 3;
00727                         dv_decode_full_frame(decoder, input, e_dv_color_rgb,
00728                                 row_pointers, pitches);
00729                         break;
00730                 case BC_YUV422:
00731 
00732 TRACE("FileDV::read_frame 50")
00733 
00734                         dv_decode_full_frame(decoder, input, e_dv_color_yuv,
00735                                 row_pointers, pitches);
00736                         break;
00737 
00738 #endif // DV_USE_FFMPEG
00739 
00740                 default:
00741                 
00742 TRACE("FileDV::read_frame 60")
00743 
00744 #ifdef DV_USE_FFMPEG
00745 
00746                         int got_picture = 0;
00747                         AVPicture temp_picture;
00748 
00749 TRACE("FileDV::read_frame 61")
00750 
00751                         temp_picture.linesize[0] = 720 * 2;
00752                         for(i = 0; i < 4; i++)
00753                                 temp_picture.data[i] = temp_pointers[i];
00754 
00755 TRACE("FileDV::read_frame 62")
00756 
00757                         if(!picture)
00758                                 picture = avcodec_alloc_frame();
00759 
00760 TRACE("FileDV::read_frame 63")
00761 
00762                         avcodec_decode_video(context,
00763                                 picture,
00764                                 &got_picture,
00765                                 input,
00766                                 output_size);
00767 
00768 TRACE("FileDV::read_frame 65")
00769 
00770                         img_convert(&temp_picture,
00771                                 PIX_FMT_YUV422,
00772                                 (AVPicture *)picture,
00773                                 (isPAL ? PIX_FMT_YUV420P : PIX_FMT_YUV411P),
00774                                 asset->width,
00775                                 asset->height);
00776 
00777 #else
00778 
00779 TRACE("FileDV::read_frame 69")
00780 
00781                         dv_decode_full_frame(decoder, input, e_dv_color_yuv,
00782                                 temp_pointers, pitches);
00783 
00784 #endif // DV_USE_FFMPEG
00785 
00786 TRACE("FileDV::read_frame 70")
00787 
00788                         cmodel_transfer(row_pointers,
00789                                 temp_pointers,
00790                                 row_pointers[0],
00791                                 row_pointers[1],
00792                                 row_pointers[2],
00793                                 temp_pointers[0],
00794                                 temp_pointers[1],
00795                                 temp_pointers[2],
00796                                 0,
00797                                 0,
00798                                 asset->width,
00799                                 asset->height,
00800                                 0,
00801                                 0,
00802                                 asset->width,
00803                                 asset->height,
00804                                 BC_YUV422,
00805                                 frame->get_color_model(),
00806                                 0,
00807                                 asset->width,
00808                                 asset->width);
00809                         break;
00810         }
00811 
00812 TRACE("FileDV::read_frame 80")
00813 
00814         free(temp_pointers);
00815         free(temp_data);
00816 
00817 UNTRACE
00818 
00819         return 0;       
00820 }
00821 
00822 int FileDV::colormodel_supported(int colormodel)
00823 {
00824         return colormodel;
00825 }
00826 
00827 int FileDV::can_copy_from(Edit *edit, int64_t position)
00828 {
00829         if(edit->asset->format == FILE_RAWDV ||
00830                         (edit->asset->format == FILE_MOV &&
00831                                 (match4(edit->asset->vcodec, QUICKTIME_DV) ||
00832                                 match4(edit->asset->vcodec, QUICKTIME_DVSD))))
00833                 return 1;
00834 
00835         return 0;
00836 }
00837 
00838 int FileDV::get_best_colormodel(Asset *asset, int driver)
00839 {
00840         switch(driver)
00841         {
00842                 case PLAYBACK_X11:
00843                         return BC_RGB888;
00844                         break;
00845                 case PLAYBACK_X11_XV:
00846                         return BC_YUV422;
00847                         break;
00848                 case PLAYBACK_DV1394:
00849                 case PLAYBACK_FIREWIRE:
00850                         return BC_COMPRESSED;
00851                         break;
00852                 case PLAYBACK_LML:
00853                 case PLAYBACK_BUZ:
00854                         return BC_YUV422P;
00855                         break;
00856                 case VIDEO4LINUX:
00857                 case VIDEO4LINUX2:
00858                 case CAPTURE_BUZ:
00859                 case CAPTURE_LML:
00860                 case VIDEO4LINUX2JPEG:
00861                         return BC_YUV422;
00862                         break;
00863                 case CAPTURE_FIREWIRE:
00864                         return BC_COMPRESSED;
00865                         break;
00866         }
00867         return BC_RGB888;
00868 }
00869 
00870 // from libdv's dv_calculate_samples, included here for use with ffmpeg and in
00871 // case user's libdv doesn't support calculate_samples (although it should).
00872 int FileDV::calculate_samples(int frame_count)
00873 {
00874         int samples = 0;
00875         if(isPAL)
00876         {
00877                 samples = asset->sample_rate / 25;
00878                 switch(asset->sample_rate)
00879                 {
00880                         case 48000:
00881                                 if(frame_count % 25 == 0)
00882                                         samples--;
00883                                 break;
00884                         case 44100:
00885                         case 32000:
00886                                 break;
00887                         default:
00888                                 samples = 0;
00889                                 break;
00890                 }
00891         }
00892         else
00893         {
00894                 samples = asset->sample_rate / 30;
00895                 switch(asset->sample_rate)
00896                 {
00897                         case 48000:
00898                                 if(frame_count % 5 != 0)
00899                                         samples += 2;
00900                                 break;
00901                         case 44100:
00902                                 if(frame_count % 300 == 0)
00903                                         samples = 1471;
00904                                 else if(frame_count % 30 == 0)
00905                                         samples = 1470;
00906                                 else if(frame_count % 2 == 0)
00907                                         samples = 1472;
00908                                 else
00909                                         samples = 1471;
00910                                 break;
00911                         case 32000:
00912                                 if(frame_count % 30 == 0)
00913                                         samples = 1068;
00914                                 else if(frame_count % 29 == 0)
00915                                         samples = 1067;
00916                                 else if(frame_count % 4 == 2)
00917                                         samples = 1067;
00918                                 else
00919                                         samples = 1068;
00920                                 break;
00921                         default:
00922                                 samples = 0;
00923                 }
00924         }
00925         return samples;
00926 }
00927 
00928 
00929 
00930 
00931 
00932 
00933 
00934 
00935 
00936 
00937 
00938 
00939 
00940 
00941 
00942 
00943 
00944 
00945 
00946 
00947 DVConfigAudio::DVConfigAudio(BC_WindowBase *parent_window, Asset *asset)
00948  : BC_Window(PROGRAM_NAME ": Audio Compression",
00949         parent_window->get_abs_cursor_x(1),
00950         parent_window->get_abs_cursor_y(1),
00951         350,
00952         250)
00953 {
00954         this->parent_window = parent_window;
00955         this->asset = asset;
00956 }
00957 
00958 DVConfigAudio::~DVConfigAudio()
00959 {
00960 
00961 }
00962 
00963 int DVConfigAudio::create_objects()
00964 {
00965         add_tool(new BC_Title(10, 10, _("There are no audio options for this format")));
00966         add_subwindow(new BC_OKButton(this));
00967         return 0;
00968 }
00969 
00970 int DVConfigAudio::close_event()
00971 {
00972         set_done(0);
00973         return 1;
00974 }
00975 
00976 
00977 
00978 
00979 
00980 
00981 DVConfigVideo::DVConfigVideo(BC_WindowBase *parent_window, Asset *asset)
00982  : BC_Window(PROGRAM_NAME ": Video Compression",
00983         parent_window->get_abs_cursor_x(1),
00984         parent_window->get_abs_cursor_y(1),
00985         350,
00986         250)
00987 {
00988         this->parent_window = parent_window;
00989         this->asset = asset;
00990 }
00991 
00992 DVConfigVideo::~DVConfigVideo()
00993 {
00994 
00995 }
00996 
00997 int DVConfigVideo::create_objects()
00998 {
00999         add_tool(new BC_Title(10, 10, _("There are no video options for this format")));
01000         add_subwindow(new BC_OKButton(this));
01001         return 0;
01002 }
01003 
01004 int DVConfigVideo::close_event()
01005 {
01006         set_done(0);
01007         return 1;
01008 }
01009 
01010 
01011 #endif

Generated on Sun Jan 8 13:38:54 2006 for Cinelerra-svn by  doxygen 1.4.4