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