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