00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <time.h>
00032 #include "avformat.h"
00033 #include "internal.h"
00034 #include "libavcodec/dvdata.h"
00035 #include "libavutil/intreadwrite.h"
00036 #include "libavutil/mathematics.h"
00037 #include "dv.h"
00038 #include "libavutil/avassert.h"
00039
00040 struct DVDemuxContext {
00041 const DVprofile* sys;
00042 AVFormatContext* fctx;
00043 AVStream* vst;
00044 AVStream* ast[4];
00045 AVPacket audio_pkt[4];
00046 uint8_t audio_buf[4][8192];
00047 int ach;
00048 int frames;
00049 uint64_t abytes;
00050 };
00051
00052 static inline uint16_t dv_audio_12to16(uint16_t sample)
00053 {
00054 uint16_t shift, result;
00055
00056 sample = (sample < 0x800) ? sample : sample | 0xf000;
00057 shift = (sample & 0xf00) >> 8;
00058
00059 if (shift < 0x2 || shift > 0xd) {
00060 result = sample;
00061 } else if (shift < 0x8) {
00062 shift--;
00063 result = (sample - (256 * shift)) << shift;
00064 } else {
00065 shift = 0xe - shift;
00066 result = ((sample + ((256 * shift) + 1)) << shift) - 1;
00067 }
00068
00069 return result;
00070 }
00071
00072
00073
00074
00075
00076
00077 static const uint8_t* dv_extract_pack(uint8_t* frame, enum dv_pack_type t)
00078 {
00079 int offs;
00080
00081 switch (t) {
00082 case dv_audio_source:
00083 offs = (80*6 + 80*16*3 + 3);
00084 break;
00085 case dv_audio_control:
00086 offs = (80*6 + 80*16*4 + 3);
00087 break;
00088 case dv_video_control:
00089 offs = (80*5 + 48 + 5);
00090 break;
00091 case dv_timecode:
00092 offs = (80*1 + 3 + 3);
00093 break;
00094 default:
00095 return NULL;
00096 }
00097
00098 return frame[offs] == t ? &frame[offs] : NULL;
00099 }
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109 static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
00110 const DVprofile *sys)
00111 {
00112 int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
00113 uint16_t lc, rc;
00114 const uint8_t* as_pack;
00115 uint8_t *pcm, ipcm;
00116
00117 as_pack = dv_extract_pack(frame, dv_audio_source);
00118 if (!as_pack)
00119 return 0;
00120
00121 smpls = as_pack[1] & 0x3f;
00122 freq = (as_pack[4] >> 3) & 0x07;
00123 quant = as_pack[4] & 0x07;
00124
00125 if (quant > 1)
00126 return -1;
00127
00128 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency))
00129 return AVERROR_INVALIDDATA;
00130
00131 size = (sys->audio_min_samples[freq] + smpls) * 4;
00132 half_ch = sys->difseg_size / 2;
00133
00134
00135
00136 ipcm = (sys->height == 720 && !(frame[1] & 0x0C)) ? 2 : 0;
00137
00138
00139 for (chan = 0; chan < sys->n_difchan; chan++) {
00140 av_assert0(ipcm<4);
00141
00142 pcm = ppcm[ipcm++];
00143 if (!pcm)
00144 break;
00145
00146 for (i = 0; i < sys->difseg_size; i++) {
00147 frame += 6 * 80;
00148 if (quant == 1 && i == half_ch) {
00149
00150 av_assert0(ipcm<4);
00151 pcm = ppcm[ipcm++];
00152 if (!pcm)
00153 break;
00154 }
00155
00156
00157 for (j = 0; j < 9; j++) {
00158 for (d = 8; d < 80; d += 2) {
00159 if (quant == 0) {
00160 of = sys->audio_shuffle[i][j] + (d - 8) / 2 * sys->audio_stride;
00161 if (of*2 >= size)
00162 continue;
00163
00164 pcm[of*2] = frame[d+1];
00165 pcm[of*2+1] = frame[d];
00166 if (pcm[of*2+1] == 0x80 && pcm[of*2] == 0x00)
00167 pcm[of*2+1] = 0;
00168 } else {
00169 lc = ((uint16_t)frame[d] << 4) |
00170 ((uint16_t)frame[d+2] >> 4);
00171 rc = ((uint16_t)frame[d+1] << 4) |
00172 ((uint16_t)frame[d+2] & 0x0f);
00173 lc = (lc == 0x800 ? 0 : dv_audio_12to16(lc));
00174 rc = (rc == 0x800 ? 0 : dv_audio_12to16(rc));
00175
00176 of = sys->audio_shuffle[i%half_ch][j] + (d - 8) / 3 * sys->audio_stride;
00177 if (of*2 >= size)
00178 continue;
00179
00180 pcm[of*2] = lc & 0xff;
00181 pcm[of*2+1] = lc >> 8;
00182 of = sys->audio_shuffle[i%half_ch+half_ch][j] +
00183 (d - 8) / 3 * sys->audio_stride;
00184 pcm[of*2] = rc & 0xff;
00185 pcm[of*2+1] = rc >> 8;
00186 ++d;
00187 }
00188 }
00189
00190 frame += 16 * 80;
00191 }
00192 }
00193 }
00194
00195 return size;
00196 }
00197
00198 static int dv_extract_audio_info(DVDemuxContext* c, uint8_t* frame)
00199 {
00200 const uint8_t* as_pack;
00201 int freq, stype, smpls, quant, i, ach;
00202
00203 as_pack = dv_extract_pack(frame, dv_audio_source);
00204 if (!as_pack || !c->sys) {
00205 c->ach = 0;
00206 return 0;
00207 }
00208
00209 smpls = as_pack[1] & 0x3f;
00210 freq = (as_pack[4] >> 3) & 0x07;
00211 stype = (as_pack[3] & 0x1f);
00212 quant = as_pack[4] & 0x07;
00213
00214 if (freq >= FF_ARRAY_ELEMS(dv_audio_frequency)) {
00215 av_log(c->fctx, AV_LOG_ERROR,
00216 "Unrecognized audio sample rate index (%d)\n", freq);
00217 return 0;
00218 }
00219
00220 if (stype > 3) {
00221 av_log(c->fctx, AV_LOG_ERROR, "stype %d is invalid\n", stype);
00222 c->ach = 0;
00223 return 0;
00224 }
00225
00226
00227 ach = ((int[4]){ 1, 0, 2, 4})[stype];
00228 if (ach == 1 && quant && freq == 2)
00229 ach = 2;
00230
00231
00232 for (i = 0; i < ach; i++) {
00233 if (!c->ast[i]) {
00234 c->ast[i] = avformat_new_stream(c->fctx, NULL);
00235 if (!c->ast[i])
00236 break;
00237 avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
00238 c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
00239 c->ast[i]->codec->codec_id = CODEC_ID_PCM_S16LE;
00240
00241 av_init_packet(&c->audio_pkt[i]);
00242 c->audio_pkt[i].size = 0;
00243 c->audio_pkt[i].data = c->audio_buf[i];
00244 c->audio_pkt[i].stream_index = c->ast[i]->index;
00245 c->audio_pkt[i].flags |= AV_PKT_FLAG_KEY;
00246 }
00247 c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
00248 c->ast[i]->codec->channels = 2;
00249 c->ast[i]->codec->bit_rate = 2 * dv_audio_frequency[freq] * 16;
00250 c->ast[i]->start_time = 0;
00251 }
00252 c->ach = i;
00253
00254 return (c->sys->audio_min_samples[freq] + smpls) * 4; ;
00255 }
00256
00257 static int dv_extract_video_info(DVDemuxContext *c, uint8_t* frame)
00258 {
00259 const uint8_t* vsc_pack;
00260 AVCodecContext* avctx;
00261 int apt, is16_9;
00262 int size = 0;
00263
00264 if (c->sys) {
00265 avctx = c->vst->codec;
00266
00267 avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
00268 c->sys->time_base.den);
00269 avctx->time_base= c->sys->time_base;
00270 if (!avctx->width)
00271 avcodec_set_dimensions(avctx, c->sys->width, c->sys->height);
00272 avctx->pix_fmt = c->sys->pix_fmt;
00273
00274
00275 vsc_pack = dv_extract_pack(frame, dv_video_control);
00276 apt = frame[4] & 0x07;
00277 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
00278 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
00279 c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
00280 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
00281 c->sys->time_base);
00282 size = c->sys->frame_size;
00283 }
00284 return size;
00285 }
00286
00287 static int bcd2int(uint8_t bcd)
00288 {
00289 int low = bcd & 0xf;
00290 int high = bcd >> 4;
00291 if (low > 9 || high > 9)
00292 return -1;
00293 return low + 10*high;
00294 }
00295
00296 static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char tc[32])
00297 {
00298 int hh, mm, ss, ff, drop_frame;
00299 const uint8_t *tc_pack;
00300
00301 tc_pack = dv_extract_pack(frame, dv_timecode);
00302 if (!tc_pack)
00303 return 0;
00304
00305 ff = bcd2int(tc_pack[1] & 0x3f);
00306 ss = bcd2int(tc_pack[2] & 0x7f);
00307 mm = bcd2int(tc_pack[3] & 0x7f);
00308 hh = bcd2int(tc_pack[4] & 0x3f);
00309 drop_frame = tc_pack[1] >> 6 & 0x1;
00310
00311 if (ff < 0 || ss < 0 || mm < 0 || hh < 0)
00312 return -1;
00313
00314
00315
00316
00317 if(c->sys->ltc_divisor == 25 || c->sys->ltc_divisor == 50) {
00318 drop_frame = 0;
00319 }
00320
00321 snprintf(tc, 32, "%02d:%02d:%02d%c%02d",
00322 hh, mm, ss, drop_frame ? ';' : ':', ff);
00323 return 1;
00324 }
00325
00326
00327
00328
00329
00330 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
00331 {
00332 DVDemuxContext *c;
00333
00334 c = av_mallocz(sizeof(DVDemuxContext));
00335 if (!c)
00336 return NULL;
00337
00338 c->vst = avformat_new_stream(s, NULL);
00339 if (!c->vst) {
00340 av_free(c);
00341 return NULL;
00342 }
00343
00344 c->sys = NULL;
00345 c->fctx = s;
00346 memset(c->ast, 0, sizeof(c->ast));
00347 c->ach = 0;
00348 c->frames = 0;
00349 c->abytes = 0;
00350
00351 c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00352 c->vst->codec->codec_id = CODEC_ID_DVVIDEO;
00353 c->vst->codec->bit_rate = 25000000;
00354 c->vst->start_time = 0;
00355
00356 return c;
00357 }
00358
00359 int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
00360 {
00361 int size = -1;
00362 int i;
00363
00364 for (i = 0; i < c->ach; i++) {
00365 if (c->ast[i] && c->audio_pkt[i].size) {
00366 *pkt = c->audio_pkt[i];
00367 c->audio_pkt[i].size = 0;
00368 size = pkt->size;
00369 break;
00370 }
00371 }
00372
00373 return size;
00374 }
00375
00376 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
00377 uint8_t* buf, int buf_size, int64_t pos)
00378 {
00379 int size, i;
00380 uint8_t *ppcm[4] = {0};
00381
00382 if (buf_size < DV_PROFILE_BYTES ||
00383 !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
00384 buf_size < c->sys->frame_size) {
00385 return -1;
00386 }
00387
00388
00389
00390 size = dv_extract_audio_info(c, buf);
00391 for (i = 0; i < c->ach; i++) {
00392 c->audio_pkt[i].pos = pos;
00393 c->audio_pkt[i].size = size;
00394 c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
00395 ppcm[i] = c->audio_buf[i];
00396 }
00397 if (c->ach)
00398 dv_extract_audio(buf, ppcm, c->sys);
00399
00400
00401
00402 if (c->sys->height == 720) {
00403 if (buf[1] & 0x0C) {
00404 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00405 } else {
00406 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00407 c->abytes += size;
00408 }
00409 } else {
00410 c->abytes += size;
00411 }
00412
00413
00414 size = dv_extract_video_info(c, buf);
00415 av_init_packet(pkt);
00416 pkt->data = buf;
00417 pkt->pos = pos;
00418 pkt->size = size;
00419 pkt->flags |= AV_PKT_FLAG_KEY;
00420 pkt->stream_index = c->vst->id;
00421 pkt->pts = c->frames;
00422
00423 c->frames++;
00424
00425 return size;
00426 }
00427
00428 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
00429 int64_t timestamp, int flags)
00430 {
00431
00432 const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
00433 int64_t offset;
00434 int64_t size = avio_size(s->pb) - s->data_offset;
00435 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
00436
00437 offset = sys->frame_size * timestamp;
00438
00439 if (size >= 0 && offset > max_offset) offset = max_offset;
00440 else if (offset < 0) offset = 0;
00441
00442 return offset + s->data_offset;
00443 }
00444
00445 void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
00446 {
00447 c->frames= frame_offset;
00448 if (c->ach)
00449 c->abytes= av_rescale_q(c->frames, c->sys->time_base,
00450 (AVRational){8, c->ast[0]->codec->bit_rate});
00451 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00452 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00453 }
00454
00455
00456
00457
00458
00459 typedef struct RawDVContext {
00460 DVDemuxContext* dv_demux;
00461 uint8_t buf[DV_MAX_FRAME_SIZE];
00462 } RawDVContext;
00463
00464 static int dv_read_timecode(AVFormatContext *s) {
00465 int ret;
00466 char timecode[32];
00467 int64_t pos = avio_tell(s->pb);
00468
00469
00470 int partial_frame_size = 3 * 80;
00471 uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) *
00472 partial_frame_size);
00473
00474 RawDVContext *c = s->priv_data;
00475 ret = avio_read(s->pb, partial_frame, partial_frame_size);
00476 if (ret < 0)
00477 goto finish;
00478
00479 if (ret < partial_frame_size) {
00480 ret = -1;
00481 goto finish;
00482 }
00483
00484 ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode);
00485 if (ret)
00486 av_dict_set(&s->metadata, "timecode", timecode, 0);
00487 else if (ret < 0)
00488 av_log(s, AV_LOG_ERROR, "Detected timecode is invalid");
00489
00490 finish:
00491 av_free(partial_frame);
00492 avio_seek(s->pb, pos, SEEK_SET);
00493 return ret;
00494 }
00495
00496 static int dv_read_header(AVFormatContext *s,
00497 AVFormatParameters *ap)
00498 {
00499 unsigned state, marker_pos = 0;
00500 RawDVContext *c = s->priv_data;
00501
00502 c->dv_demux = avpriv_dv_init_demux(s);
00503 if (!c->dv_demux)
00504 return -1;
00505
00506 state = avio_rb32(s->pb);
00507 while ((state & 0xffffff7f) != 0x1f07003f) {
00508 if (url_feof(s->pb)) {
00509 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
00510 return -1;
00511 }
00512 if (state == 0x003f0700 || state == 0xff3f0700)
00513 marker_pos = avio_tell(s->pb);
00514 if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) {
00515 avio_seek(s->pb, -163, SEEK_CUR);
00516 state = avio_rb32(s->pb);
00517 break;
00518 }
00519 state = (state << 8) | avio_r8(s->pb);
00520 }
00521 AV_WB32(c->buf, state);
00522
00523 if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
00524 avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
00525 return AVERROR(EIO);
00526
00527 c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
00528 if (!c->dv_demux->sys) {
00529 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
00530 return -1;
00531 }
00532
00533 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
00534 c->dv_demux->sys->time_base);
00535
00536 if (s->pb->seekable)
00537 dv_read_timecode(s);
00538
00539 return 0;
00540 }
00541
00542
00543 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
00544 {
00545 int size;
00546 RawDVContext *c = s->priv_data;
00547
00548 size = avpriv_dv_get_packet(c->dv_demux, pkt);
00549
00550 if (size < 0) {
00551 int64_t pos = avio_tell(s->pb);
00552 if (!c->dv_demux->sys)
00553 return AVERROR(EIO);
00554 size = c->dv_demux->sys->frame_size;
00555 if (avio_read(s->pb, c->buf, size) <= 0)
00556 return AVERROR(EIO);
00557
00558 size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
00559 }
00560
00561 return size;
00562 }
00563
00564 static int dv_read_seek(AVFormatContext *s, int stream_index,
00565 int64_t timestamp, int flags)
00566 {
00567 RawDVContext *r = s->priv_data;
00568 DVDemuxContext *c = r->dv_demux;
00569 int64_t offset = dv_frame_offset(s, c, timestamp, flags);
00570
00571 if (avio_seek(s->pb, offset, SEEK_SET) < 0)
00572 return -1;
00573
00574 dv_offset_reset(c, offset / c->sys->frame_size);
00575 return 0;
00576 }
00577
00578 static int dv_read_close(AVFormatContext *s)
00579 {
00580 RawDVContext *c = s->priv_data;
00581 av_free(c->dv_demux);
00582 return 0;
00583 }
00584
00585 static int dv_probe(AVProbeData *p)
00586 {
00587 unsigned state, marker_pos = 0;
00588 int i;
00589 int matches = 0;
00590 int secondary_matches = 0;
00591
00592 if (p->buf_size < 5)
00593 return 0;
00594
00595 state = AV_RB32(p->buf);
00596 for (i = 4; i < p->buf_size; i++) {
00597 if ((state & 0xffffff7f) == 0x1f07003f)
00598 matches++;
00599
00600
00601 if ((state & 0xff07ff7f) == 0x1f07003f)
00602 secondary_matches++;
00603 if (state == 0x003f0700 || state == 0xff3f0700)
00604 marker_pos = i;
00605 if (state == 0xff3f0701 && i - marker_pos == 80)
00606 matches++;
00607 state = (state << 8) | p->buf[i];
00608 }
00609
00610 if (matches && p->buf_size / matches < 1024*1024) {
00611 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
00612 return AVPROBE_SCORE_MAX*3/4;
00613 return AVPROBE_SCORE_MAX/4;
00614 }
00615 return 0;
00616 }
00617
00618 #if CONFIG_DV_DEMUXER
00619 AVInputFormat ff_dv_demuxer = {
00620 .name = "dv",
00621 .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
00622 .priv_data_size = sizeof(RawDVContext),
00623 .read_probe = dv_probe,
00624 .read_header = dv_read_header,
00625 .read_packet = dv_read_packet,
00626 .read_close = dv_read_close,
00627 .read_seek = dv_read_seek,
00628 .extensions = "dv,dif",
00629 };
00630 #endif