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
00271
00272 vsc_pack = dv_extract_pack(frame, dv_video_control);
00273 apt = frame[4] & 0x07;
00274 is16_9 = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
00275 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
00276 c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
00277 avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
00278 c->sys->time_base);
00279 size = c->sys->frame_size;
00280 }
00281 return size;
00282 }
00283
00284 static int bcd2int(uint8_t bcd)
00285 {
00286 int low = bcd & 0xf;
00287 int high = bcd >> 4;
00288 if (low > 9 || high > 9)
00289 return -1;
00290 return low + 10*high;
00291 }
00292
00293 static int dv_extract_timecode(DVDemuxContext* c, uint8_t* frame, char tc[32])
00294 {
00295 int hh, mm, ss, ff, drop_frame;
00296 const uint8_t *tc_pack;
00297
00298 tc_pack = dv_extract_pack(frame, dv_timecode);
00299 if (!tc_pack)
00300 return 0;
00301
00302 ff = bcd2int(tc_pack[1] & 0x3f);
00303 ss = bcd2int(tc_pack[2] & 0x7f);
00304 mm = bcd2int(tc_pack[3] & 0x7f);
00305 hh = bcd2int(tc_pack[4] & 0x3f);
00306 drop_frame = tc_pack[1] >> 6 & 0x1;
00307
00308 if (ff < 0 || ss < 0 || mm < 0 || hh < 0)
00309 return -1;
00310
00311
00312
00313
00314 if(c->sys->ltc_divisor == 25 || c->sys->ltc_divisor == 50) {
00315 drop_frame = 0;
00316 }
00317
00318 snprintf(tc, 32, "%02d:%02d:%02d%c%02d",
00319 hh, mm, ss, drop_frame ? ';' : ':', ff);
00320 return 1;
00321 }
00322
00323
00324
00325
00326
00327 DVDemuxContext* avpriv_dv_init_demux(AVFormatContext *s)
00328 {
00329 DVDemuxContext *c;
00330
00331 c = av_mallocz(sizeof(DVDemuxContext));
00332 if (!c)
00333 return NULL;
00334
00335 c->vst = avformat_new_stream(s, NULL);
00336 if (!c->vst) {
00337 av_free(c);
00338 return NULL;
00339 }
00340
00341 c->sys = NULL;
00342 c->fctx = s;
00343 memset(c->ast, 0, sizeof(c->ast));
00344 c->ach = 0;
00345 c->frames = 0;
00346 c->abytes = 0;
00347
00348 c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
00349 c->vst->codec->codec_id = CODEC_ID_DVVIDEO;
00350 c->vst->codec->bit_rate = 25000000;
00351 c->vst->start_time = 0;
00352
00353 return c;
00354 }
00355
00356 int avpriv_dv_get_packet(DVDemuxContext *c, AVPacket *pkt)
00357 {
00358 int size = -1;
00359 int i;
00360
00361 for (i = 0; i < c->ach; i++) {
00362 if (c->ast[i] && c->audio_pkt[i].size) {
00363 *pkt = c->audio_pkt[i];
00364 c->audio_pkt[i].size = 0;
00365 size = pkt->size;
00366 break;
00367 }
00368 }
00369
00370 return size;
00371 }
00372
00373 int avpriv_dv_produce_packet(DVDemuxContext *c, AVPacket *pkt,
00374 uint8_t* buf, int buf_size, int64_t pos)
00375 {
00376 int size, i;
00377 uint8_t *ppcm[4] = {0};
00378
00379 if (buf_size < DV_PROFILE_BYTES ||
00380 !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
00381 buf_size < c->sys->frame_size) {
00382 return -1;
00383 }
00384
00385
00386
00387 size = dv_extract_audio_info(c, buf);
00388 for (i = 0; i < c->ach; i++) {
00389 c->audio_pkt[i].pos = pos;
00390 c->audio_pkt[i].size = size;
00391 c->audio_pkt[i].pts = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
00392 ppcm[i] = c->audio_buf[i];
00393 }
00394 if (c->ach)
00395 dv_extract_audio(buf, ppcm, c->sys);
00396
00397
00398
00399 if (c->sys->height == 720) {
00400 if (buf[1] & 0x0C) {
00401 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00402 } else {
00403 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00404 c->abytes += size;
00405 }
00406 } else {
00407 c->abytes += size;
00408 }
00409
00410
00411 size = dv_extract_video_info(c, buf);
00412 av_init_packet(pkt);
00413 pkt->data = buf;
00414 pkt->pos = pos;
00415 pkt->size = size;
00416 pkt->flags |= AV_PKT_FLAG_KEY;
00417 pkt->stream_index = c->vst->id;
00418 pkt->pts = c->frames;
00419
00420 c->frames++;
00421
00422 return size;
00423 }
00424
00425 static int64_t dv_frame_offset(AVFormatContext *s, DVDemuxContext *c,
00426 int64_t timestamp, int flags)
00427 {
00428
00429 const DVprofile* sys = avpriv_dv_codec_profile(c->vst->codec);
00430 int64_t offset;
00431 int64_t size = avio_size(s->pb) - s->data_offset;
00432 int64_t max_offset = ((size-1) / sys->frame_size) * sys->frame_size;
00433
00434 offset = sys->frame_size * timestamp;
00435
00436 if (size >= 0 && offset > max_offset) offset = max_offset;
00437 else if (offset < 0) offset = 0;
00438
00439 return offset + s->data_offset;
00440 }
00441
00442 void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
00443 {
00444 c->frames= frame_offset;
00445 if (c->ach)
00446 c->abytes= av_rescale_q(c->frames, c->sys->time_base,
00447 (AVRational){8, c->ast[0]->codec->bit_rate});
00448 c->audio_pkt[0].size = c->audio_pkt[1].size = 0;
00449 c->audio_pkt[2].size = c->audio_pkt[3].size = 0;
00450 }
00451
00452
00453
00454
00455
00456 typedef struct RawDVContext {
00457 DVDemuxContext* dv_demux;
00458 uint8_t buf[DV_MAX_FRAME_SIZE];
00459 } RawDVContext;
00460
00461 static int dv_read_timecode(AVFormatContext *s) {
00462 int ret;
00463 char timecode[32];
00464 int64_t pos = avio_tell(s->pb);
00465
00466
00467 int partial_frame_size = 3 * 80;
00468 uint8_t *partial_frame = av_mallocz(sizeof(*partial_frame) *
00469 partial_frame_size);
00470
00471 RawDVContext *c = s->priv_data;
00472 ret = avio_read(s->pb, partial_frame, partial_frame_size);
00473 if (ret < 0)
00474 goto finish;
00475
00476 if (ret < partial_frame_size) {
00477 ret = -1;
00478 goto finish;
00479 }
00480
00481 ret = dv_extract_timecode(c->dv_demux, partial_frame, timecode);
00482 if (ret)
00483 av_dict_set(&s->metadata, "timecode", timecode, 0);
00484 else if (ret < 0)
00485 av_log(s, AV_LOG_ERROR, "Detected timecode is invalid");
00486
00487 finish:
00488 av_free(partial_frame);
00489 avio_seek(s->pb, pos, SEEK_SET);
00490 return ret;
00491 }
00492
00493 static int dv_read_header(AVFormatContext *s,
00494 AVFormatParameters *ap)
00495 {
00496 unsigned state, marker_pos = 0;
00497 RawDVContext *c = s->priv_data;
00498
00499 c->dv_demux = avpriv_dv_init_demux(s);
00500 if (!c->dv_demux)
00501 return -1;
00502
00503 state = avio_rb32(s->pb);
00504 while ((state & 0xffffff7f) != 0x1f07003f) {
00505 if (url_feof(s->pb)) {
00506 av_log(s, AV_LOG_ERROR, "Cannot find DV header.\n");
00507 return -1;
00508 }
00509 if (state == 0x003f0700 || state == 0xff3f0700)
00510 marker_pos = avio_tell(s->pb);
00511 if (state == 0xff3f0701 && avio_tell(s->pb) - marker_pos == 80) {
00512 avio_seek(s->pb, -163, SEEK_CUR);
00513 state = avio_rb32(s->pb);
00514 break;
00515 }
00516 state = (state << 8) | avio_r8(s->pb);
00517 }
00518 AV_WB32(c->buf, state);
00519
00520 if (avio_read(s->pb, c->buf + 4, DV_PROFILE_BYTES - 4) <= 0 ||
00521 avio_seek(s->pb, -DV_PROFILE_BYTES, SEEK_CUR) < 0)
00522 return AVERROR(EIO);
00523
00524 c->dv_demux->sys = avpriv_dv_frame_profile(c->dv_demux->sys, c->buf, DV_PROFILE_BYTES);
00525 if (!c->dv_demux->sys) {
00526 av_log(s, AV_LOG_ERROR, "Can't determine profile of DV input stream.\n");
00527 return -1;
00528 }
00529
00530 s->bit_rate = av_rescale_q(c->dv_demux->sys->frame_size, (AVRational){8,1},
00531 c->dv_demux->sys->time_base);
00532
00533 if (s->pb->seekable)
00534 dv_read_timecode(s);
00535
00536 return 0;
00537 }
00538
00539
00540 static int dv_read_packet(AVFormatContext *s, AVPacket *pkt)
00541 {
00542 int size;
00543 RawDVContext *c = s->priv_data;
00544
00545 size = avpriv_dv_get_packet(c->dv_demux, pkt);
00546
00547 if (size < 0) {
00548 int64_t pos = avio_tell(s->pb);
00549 if (!c->dv_demux->sys)
00550 return AVERROR(EIO);
00551 size = c->dv_demux->sys->frame_size;
00552 if (avio_read(s->pb, c->buf, size) <= 0)
00553 return AVERROR(EIO);
00554
00555 size = avpriv_dv_produce_packet(c->dv_demux, pkt, c->buf, size, pos);
00556 }
00557
00558 return size;
00559 }
00560
00561 static int dv_read_seek(AVFormatContext *s, int stream_index,
00562 int64_t timestamp, int flags)
00563 {
00564 RawDVContext *r = s->priv_data;
00565 DVDemuxContext *c = r->dv_demux;
00566 int64_t offset = dv_frame_offset(s, c, timestamp, flags);
00567
00568 if (avio_seek(s->pb, offset, SEEK_SET) < 0)
00569 return -1;
00570
00571 dv_offset_reset(c, offset / c->sys->frame_size);
00572 return 0;
00573 }
00574
00575 static int dv_read_close(AVFormatContext *s)
00576 {
00577 RawDVContext *c = s->priv_data;
00578 av_free(c->dv_demux);
00579 return 0;
00580 }
00581
00582 static int dv_probe(AVProbeData *p)
00583 {
00584 unsigned state, marker_pos = 0;
00585 int i;
00586 int matches = 0;
00587 int secondary_matches = 0;
00588
00589 if (p->buf_size < 5)
00590 return 0;
00591
00592 state = AV_RB32(p->buf);
00593 for (i = 4; i < p->buf_size; i++) {
00594 if ((state & 0xffffff7f) == 0x1f07003f)
00595 matches++;
00596
00597
00598 if ((state & 0xff07ff7f) == 0x1f07003f)
00599 secondary_matches++;
00600 if (state == 0x003f0700 || state == 0xff3f0700)
00601 marker_pos = i;
00602 if (state == 0xff3f0701 && i - marker_pos == 80)
00603 matches++;
00604 state = (state << 8) | p->buf[i];
00605 }
00606
00607 if (matches && p->buf_size / matches < 1024*1024) {
00608 if (matches > 4 || (secondary_matches >= 10 && p->buf_size / secondary_matches < 24000))
00609 return AVPROBE_SCORE_MAX*3/4;
00610 return AVPROBE_SCORE_MAX/4;
00611 }
00612 return 0;
00613 }
00614
00615 #if CONFIG_DV_DEMUXER
00616 AVInputFormat ff_dv_demuxer = {
00617 .name = "dv",
00618 .long_name = NULL_IF_CONFIG_SMALL("DV video format"),
00619 .priv_data_size = sizeof(RawDVContext),
00620 .read_probe = dv_probe,
00621 .read_header = dv_read_header,
00622 .read_packet = dv_read_packet,
00623 .read_close = dv_read_close,
00624 .read_seek = dv_read_seek,
00625 .extensions = "dv,dif",
00626 };
00627 #endif