static int dv_assemble_frame(DVMuxContext *c, AVStream* st, uint8_t* data, int data_size, uint8_t** frame) { int i, reqasize; *frame = &c->frame_buf[0]; reqasize = 4 * dv_audio_frame_size(c->sys, c->frames); switch (st->codec->codec_type) { case AVMEDIA_TYPE_VIDEO: /* FIXME: we have to have more sensible approach than this one */ if (c->has_video) av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient audio data or severe sync problem.\n", c->frames); memcpy(*frame, data, c->sys->frame_size); c->has_video = 1; break; case AVMEDIA_TYPE_AUDIO: for (i = 0; i < c->n_ast && st != c->ast[i]; i++); /* FIXME: we have to have more sensible approach than this one */ if (av_fifo_size(c->audio_data[i]) + data_size >= 100*AVCODEC_MAX_AUDIO_FRAME_SIZE) av_log(st->codec, AV_LOG_ERROR, "Can't process DV frame #%d. Insufficient video data or severe sync problem.\n", c->frames); av_fifo_generic_write(c->audio_data[i], data, data_size, NULL); /* Let us see if we've got enough audio for one DV frame. */ c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); break; default: break; } /* Let us see if we have enough data to construct one DV frame. */ if (c->has_video == 1 && c->has_audio + 1 == 1 << c->n_ast) { dv_inject_metadata(c, *frame); c->has_audio = 0; for (i=0; i < c->n_ast; i++) { dv_inject_audio(c, i, *frame); av_fifo_drain(c->audio_data[i], reqasize); c->has_audio |= ((reqasize <= av_fifo_size(c->audio_data[i])) << i); } c->has_video = 0; c->frames++; return c->sys->frame_size; } return 0; }
static void dv_inject_audio(DVMuxContext *c, int channel, uint8_t* frame_ptr) { int i, j, d, of, size; size = 4 * dv_audio_frame_size(c->sys, c->frames); frame_ptr += channel * c->sys->difseg_size * 150 * 80; for (i = 0; i < c->sys->difseg_size; i++) { frame_ptr += 6 * 80; /* skip DIF segment header */ for (j = 0; j < 9; j++) { dv_write_pack(dv_aaux_packs_dist[i][j], c, &frame_ptr[3], i); for (d = 8; d < 80; d+=2) { of = c->sys->audio_shuffle[i][j] + (d - 8)/2 * c->sys->audio_stride; if (of*2 >= size) continue; frame_ptr[d] = av_fifo_peek(c->audio_data[channel], of*2); frame_ptr[d+1] = av_fifo_peek(c->audio_data[channel], of*2+1); } frame_ptr += 16 * 80; /* 15 Video DIFs + 1 Audio DIF */ } } }
static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t* buf) { struct tm tc; time_t ct; int ltc_frame; buf[0] = (uint8_t)pack_id; switch (pack_id) { case dv_timecode: ct = (time_t)(c->frames / ((float)c->sys->frame_rate / (float)c->sys->frame_rate_base)); brktimegm(ct, &tc); /* * LTC drop-frame frame counter drops two frames (0 and 1) every * minute, unless it is exactly divisible by 10 */ ltc_frame = (c->frames + 2*ct/60 - 2*ct/600) % c->sys->ltc_divisor; buf[1] = (0 << 7) | /* Color fame: 0 - unsync; 1 - sync mode */ (1 << 6) | /* Drop frame timecode: 0 - nondrop; 1 - drop */ ((ltc_frame / 10) << 4) | /* Tens of frames */ (ltc_frame % 10); /* Units of frames */ buf[2] = (1 << 7) | /* Biphase mark polarity correction: 0 - even; 1 - odd */ ((tc.tm_sec / 10) << 4) | /* Tens of seconds */ (tc.tm_sec % 10); /* Units of seconds */ buf[3] = (1 << 7) | /* Binary group flag BGF0 */ ((tc.tm_min / 10) << 4) | /* Tens of minutes */ (tc.tm_min % 10); /* Units of minutes */ buf[4] = (1 << 7) | /* Binary group flag BGF2 */ (1 << 6) | /* Binary group flag BGF1 */ ((tc.tm_hour / 10) << 4) | /* Tens of hours */ (tc.tm_hour % 10); /* Units of hours */ break; case dv_audio_source: /* AAUX source pack */ buf[1] = (0 << 7) | /* locked mode */ (1 << 6) | /* reserved -- always 1 */ (dv_audio_frame_size(c->sys, c->frames) - c->sys->audio_min_samples[0]); /* # of samples */ buf[2] = (0 << 7) | /* multi-stereo */ (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */ (0 << 4) | /* pair bit: 0 -- one pair of channels */ 0; /* audio mode */ buf[3] = (1 << 7) | /* res */ (1 << 6) | /* multi-language flag */ (c->sys->dsf << 5) | /* system: 60fields/50fields */ (c->sys->n_difchan & 2); /* definition: 0 -- 25Mbps, 2 -- 50Mbps */ buf[4] = (1 << 7) | /* emphasis: 1 -- off */ (0 << 6) | /* emphasis time constant: 0 -- reserved */ (0 << 3) | /* frequency: 0 -- 48Khz, 1 -- 44,1Khz, 2 -- 32Khz */ 0; /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */ break; case dv_audio_control: buf[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */ (1 << 4) | /* input source: 1 -- digital input */ (3 << 2) | /* compression: 3 -- no information */ 0; /* misc. info/SMPTE emphasis off */ buf[2] = (1 << 7) | /* recording start point: 1 -- no */ (1 << 6) | /* recording end point: 1 -- no */ (1 << 3) | /* recording mode: 1 -- original */ 7; buf[3] = (1 << 7) | /* direction: 1 -- forward */ (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0x20 : /* speed */ c->sys->ltc_divisor*4); buf[4] = (1 << 7) | /* reserved -- always 1 */ 0x7f; /* genre category */ break; case dv_audio_recdate: case dv_video_recdate: /* VAUX recording date */ ct = c->start_time + (time_t)(c->frames / ((float)c->sys->frame_rate / (float)c->sys->frame_rate_base)); brktimegm(ct, &tc); buf[1] = 0xff; /* ds, tm, tens of time zone, units of time zone */ /* 0xff is very likely to be "unknown" */ buf[2] = (3 << 6) | /* reserved -- always 1 */ ((tc.tm_mday / 10) << 4) | /* Tens of day */ (tc.tm_mday % 10); /* Units of day */ buf[3] = /* we set high 4 bits to 0, shouldn't we set them to week? */ ((tc.tm_mon / 10) << 4) | /* Tens of month */ (tc.tm_mon % 10); /* Units of month */ buf[4] = (((tc.tm_year % 100) / 10) << 4) | /* Tens of year */ (tc.tm_year % 10); /* Units of year */ break; case dv_audio_rectime: /* AAUX recording time */ case dv_video_rectime: /* VAUX recording time */ ct = c->start_time + (time_t)(c->frames / ((float)c->sys->frame_rate / (float)c->sys->frame_rate_base)); brktimegm(ct, &tc); buf[1] = (3 << 6) | /* reserved -- always 1 */ 0x3f; /* tens of frame, units of frame: 0x3f - "unknown" ? */ buf[2] = (1 << 7) | /* reserved -- always 1 */ ((tc.tm_sec / 10) << 4) | /* Tens of seconds */ (tc.tm_sec % 10); /* Units of seconds */ buf[3] = (1 << 7) | /* reserved -- always 1 */ ((tc.tm_min / 10) << 4) | /* Tens of minutes */ (tc.tm_min % 10); /* Units of minutes */ buf[4] = (3 << 6) | /* reserved -- always 1 */ ((tc.tm_hour / 10) << 4) | /* Tens of hours */ (tc.tm_hour % 10); /* Units of hours */ break; default: buf[1] = buf[2] = buf[3] = buf[4] = 0xff; } return 5; }
static int dv_write_pack(enum dv_pack_type pack_id, DVMuxContext *c, uint8_t *buf, int seq) { int time_code; buf[0] = (uint8_t)pack_id; switch (pack_id) { case dv_timecode: time_code = c->frames + c->timecode_start; /* * LTC drop-frame frame counter drops two frames (0 and 1) every * minute, unless it is exactly divisible by 10 */ if (c->timecode_drop_frame) time_code = ff_framenum_to_drop_timecode(time_code, c->sys->ltc_divisor); buf[1] = (0 << 7) | /* Color fame: 0 - unsync; 1 - sync mode */ /* Drop frame timecode: 0 - nondrop; 1 - drop */ (c->timecode_drop_frame << 6) | (((time_code % c->sys->ltc_divisor) / 10) << 4) | /* Tens of frames */ ((time_code % c->sys->ltc_divisor) % 10); /* Units of frames */ buf[2] = (1 << 7) | /* Biphase mark polarity correction: 0 - even; 1 - odd */ ((((time_code / c->sys->ltc_divisor) % 60) / 10) << 4) | /* Tens of seconds */ (((time_code / c->sys->ltc_divisor) % 60) % 10); /* Units of seconds */ buf[3] = (1 << 7) | /* Binary group flag BGF0 */ ((((time_code / (c->sys->ltc_divisor * 60)) % 60) / 10) << 4) | /* Tens of minutes */ (((time_code / (c->sys->ltc_divisor * 60)) % 60) % 10); /* Units of minutes */ buf[4] = (1 << 7) | /* Binary group flag BGF2 */ (1 << 6) | /* Binary group flag BGF1 */ ((((time_code / (c->sys->ltc_divisor * 3600) % 24)) / 10) << 4) | /* Tens of hours */ (((time_code / (c->sys->ltc_divisor * 3600) % 24)) % 10); /* Units of hours */ break; case dv_audio_source: /* AAUX source pack */ buf[1] = (1 << 7) | /* locked mode -- SMPTE only supports locked mode */ (1 << 6) | /* reserved -- always 1 */ (dv_audio_frame_size(c->sys, c->frames) - c->sys->audio_min_samples[0]); /* # of samples */ buf[2] = (0 << 7) | /* multi-stereo */ (0 << 5) | /* #of audio channels per block: 0 -- 1 channel */ (0 << 4) | /* pair bit: 0 -- one pair of channels */ (seq >= c->sys->difseg_size/2); /* audio mode (1st or 2nd channel) */ buf[3] = (1 << 7) | /* res */ (1 << 6) | /* multi-language flag */ (c->sys->dsf << 5) | /* system: 60fields/50fields */ (DV_PROFILE_IS_HD(c->sys) ? 0x3 : c->sys->video_stype ? 2 : 0); /* stype */ buf[4] = (1 << 7) | /* emphasis: 1 -- off */ (0 << 6) | /* emphasis time constant: 0 -- reserved */ (0 << 3) | /* frequency: 0 -- 48kHz, 1 -- 44,1kHz, 2 -- 32kHz */ 0; /* quantization: 0 -- 16bit linear, 1 -- 12bit nonlinear */ break; case dv_audio_control: buf[1] = (0 << 6) | /* copy protection: 0 -- unrestricted */ (1 << 4) | /* input source: 1 -- digital input */ (3 << 2) | /* compression: 3 -- no information */ 0; /* misc. info/SMPTE emphasis off */ buf[2] = (1 << 7) | /* recording start point: 1 -- no */ (1 << 6) | /* recording end point: 1 -- no */ (1 << 3) | /* recording mode: 1 -- original */ 7; buf[3] = (1 << 7) | /* direction: 1 -- forward */ (c->sys->pix_fmt == PIX_FMT_YUV420P ? 0x20 : /* speed */ c->sys->ltc_divisor * 4); buf[4] = (1 << 7) | /* reserved -- always 1 */ 0x7f; /* genre category */ break; default: buf[1] = buf[2] = buf[3] = buf[4] = 0xff; } return 5; }