~siretart/libav/trusty

« back to all changes in this revision

Viewing changes to libavformat/dv.c

  • Committer: Reinhard Tartler
  • Date: 2013-10-23 03:04:17 UTC
  • mfrom: (1.3.36 sid)
  • Revision ID: siretart@tauware.de-20131023030417-1o6mpkl1l0raifjt
mergeĀ fromĀ debian

Show diffs side-by-side

added added

removed removed

Lines of Context:
31
31
#include <time.h>
32
32
#include "avformat.h"
33
33
#include "internal.h"
 
34
#include "libavcodec/dv_profile.h"
34
35
#include "libavcodec/dvdata.h"
 
36
#include "libavutil/channel_layout.h"
35
37
#include "libavutil/intreadwrite.h"
36
38
#include "libavutil/mathematics.h"
37
39
#include "dv.h"
94
96
    return frame[offs] == t ? &frame[offs] : NULL;
95
97
}
96
98
 
 
99
static const int dv_audio_frequency[3] = {
 
100
    48000, 44100, 32000,
 
101
};
 
102
 
97
103
/*
98
104
 * There's a couple of assumptions being made here:
99
105
 * 1. By default we silence erroneous (0x8000/16bit 0x800/12bit) audio samples.
102
108
 * 3. Audio is always returned as 16bit linear samples: 12bit nonlinear samples
103
109
 *    are converted into 16bit linear ones.
104
110
 */
105
 
static int dv_extract_audio(uint8_t* frame, uint8_t* ppcm[4],
 
111
static int dv_extract_audio(uint8_t *frame, uint8_t **ppcm,
106
112
                            const DVprofile *sys)
107
113
{
108
114
    int size, chan, i, j, d, of, smpls, freq, quant, half_ch;
225
231
 
226
232
    /* Dynamic handling of the audio streams in DV */
227
233
    for (i = 0; i < ach; i++) {
228
 
       if (!c->ast[i]) {
229
 
           c->ast[i] = avformat_new_stream(c->fctx, NULL);
230
 
           if (!c->ast[i])
231
 
               break;
232
 
           avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
233
 
           c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
234
 
           c->ast[i]->codec->codec_id   = CODEC_ID_PCM_S16LE;
 
234
        if (!c->ast[i]) {
 
235
            c->ast[i] = avformat_new_stream(c->fctx, NULL);
 
236
            if (!c->ast[i])
 
237
                break;
 
238
            avpriv_set_pts_info(c->ast[i], 64, 1, 30000);
 
239
            c->ast[i]->codec->codec_type = AVMEDIA_TYPE_AUDIO;
 
240
            c->ast[i]->codec->codec_id   = AV_CODEC_ID_PCM_S16LE;
235
241
 
236
 
           av_init_packet(&c->audio_pkt[i]);
237
 
           c->audio_pkt[i].size         = 0;
238
 
           c->audio_pkt[i].data         = c->audio_buf[i];
239
 
           c->audio_pkt[i].stream_index = c->ast[i]->index;
240
 
           c->audio_pkt[i].flags       |= AV_PKT_FLAG_KEY;
241
 
       }
242
 
       c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
243
 
       c->ast[i]->codec->channels    = 2;
244
 
       c->ast[i]->codec->bit_rate    = 2 * dv_audio_frequency[freq] * 16;
245
 
       c->ast[i]->start_time         = 0;
 
242
            av_init_packet(&c->audio_pkt[i]);
 
243
            c->audio_pkt[i].size         = 0;
 
244
            c->audio_pkt[i].data         = c->audio_buf[i];
 
245
            c->audio_pkt[i].stream_index = c->ast[i]->index;
 
246
            c->audio_pkt[i].flags       |= AV_PKT_FLAG_KEY;
 
247
        }
 
248
        c->ast[i]->codec->sample_rate = dv_audio_frequency[freq];
 
249
        c->ast[i]->codec->channels    = 2;
 
250
        c->ast[i]->codec->channel_layout = AV_CH_LAYOUT_STEREO;
 
251
        c->ast[i]->codec->bit_rate    = 2 * dv_audio_frequency[freq] * 16;
 
252
        c->ast[i]->start_time         = 0;
246
253
    }
247
254
    c->ach = i;
248
255
 
260
267
        avctx = c->vst->codec;
261
268
 
262
269
        avpriv_set_pts_info(c->vst, 64, c->sys->time_base.num,
263
 
                        c->sys->time_base.den);
 
270
                            c->sys->time_base.den);
264
271
        avctx->time_base= c->sys->time_base;
265
272
        if (!avctx->width){
266
273
            avctx->width = c->sys->width;
272
279
        vsc_pack = dv_extract_pack(frame, dv_video_control);
273
280
        apt      = frame[4] & 0x07;
274
281
        is16_9   = (vsc_pack && ((vsc_pack[2] & 0x07) == 0x02 ||
275
 
                                (!apt && (vsc_pack[2] & 0x07) == 0x07)));
 
282
                                 (!apt && (vsc_pack[2] & 0x07) == 0x07)));
276
283
        c->vst->sample_aspect_ratio = c->sys->sar[is16_9];
277
284
        avctx->bit_rate = av_rescale_q(c->sys->frame_size, (AVRational){8,1},
278
285
                                       c->sys->time_base);
299
306
        return NULL;
300
307
    }
301
308
 
302
 
    c->sys  = NULL;
303
 
    c->fctx = s;
304
 
    memset(c->ast, 0, sizeof(c->ast));
305
 
    c->ach    = 0;
306
 
    c->frames = 0;
307
 
    c->abytes = 0;
308
 
 
 
309
    c->fctx                   = s;
309
310
    c->vst->codec->codec_type = AVMEDIA_TYPE_VIDEO;
310
 
    c->vst->codec->codec_id   = CODEC_ID_DVVIDEO;
 
311
    c->vst->codec->codec_id   = AV_CODEC_ID_DVVIDEO;
311
312
    c->vst->codec->bit_rate   = 25000000;
312
313
    c->vst->start_time        = 0;
313
314
 
320
321
    int i;
321
322
 
322
323
    for (i = 0; i < c->ach; i++) {
323
 
       if (c->ast[i] && c->audio_pkt[i].size) {
324
 
           *pkt = c->audio_pkt[i];
325
 
           c->audio_pkt[i].size = 0;
326
 
           size = pkt->size;
327
 
           break;
328
 
       }
 
324
        if (c->ast[i] && c->audio_pkt[i].size) {
 
325
            *pkt = c->audio_pkt[i];
 
326
            c->audio_pkt[i].size = 0;
 
327
            size = pkt->size;
 
328
            break;
 
329
        }
329
330
    }
330
331
 
331
332
    return size;
335
336
                      uint8_t* buf, int buf_size)
336
337
{
337
338
    int size, i;
338
 
    uint8_t *ppcm[4] = {0};
 
339
    uint8_t *ppcm[5] = { 0 };
339
340
 
340
341
    if (buf_size < DV_PROFILE_BYTES ||
341
342
        !(c->sys = avpriv_dv_frame_profile(c->sys, buf, buf_size)) ||
342
343
        buf_size < c->sys->frame_size) {
343
 
          return -1;   /* Broken frame, or not enough data */
 
344
        return -1;   /* Broken frame, or not enough data */
344
345
    }
345
346
 
346
347
    /* Queueing audio packet */
347
348
    /* FIXME: in case of no audio/bad audio we have to do something */
348
349
    size = dv_extract_audio_info(c, buf);
349
350
    for (i = 0; i < c->ach; i++) {
350
 
       c->audio_pkt[i].size = size;
351
 
       c->audio_pkt[i].pts  = c->abytes * 30000*8 / c->ast[i]->codec->bit_rate;
352
 
       ppcm[i] = c->audio_buf[i];
 
351
        c->audio_pkt[i].size = size;
 
352
        c->audio_pkt[i].pts  = c->abytes * 30000 * 8 / c->ast[i]->codec->bit_rate;
 
353
        ppcm[i] = c->audio_buf[i];
353
354
    }
354
355
    if (c->ach)
355
356
        dv_extract_audio(buf, ppcm, c->sys);
373
374
    pkt->data         = buf;
374
375
    pkt->size         = size;
375
376
    pkt->flags       |= AV_PKT_FLAG_KEY;
376
 
    pkt->stream_index = c->vst->id;
 
377
    pkt->stream_index = c->vst->index;
377
378
    pkt->pts          = c->frames;
378
379
 
379
380
    c->frames++;
398
399
    return offset + s->data_offset;
399
400
}
400
401
 
401
 
void dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
 
402
void ff_dv_offset_reset(DVDemuxContext *c, int64_t frame_offset)
402
403
{
403
404
    c->frames= frame_offset;
404
405
    if (c->ach)
417
418
    uint8_t         buf[DV_MAX_FRAME_SIZE];
418
419
} RawDVContext;
419
420
 
420
 
static int dv_read_header(AVFormatContext *s,
421
 
                          AVFormatParameters *ap)
 
421
static int dv_read_header(AVFormatContext *s)
422
422
{
423
423
    unsigned state, marker_pos = 0;
424
424
    RawDVContext *c = s->priv_data;
488
488
    DVDemuxContext *c = r->dv_demux;
489
489
    int64_t offset    = dv_frame_offset(s, c, timestamp, flags);
490
490
 
491
 
    dv_offset_reset(c, offset / c->sys->frame_size);
 
491
    if (avio_seek(s->pb, offset, SEEK_SET) < 0)
 
492
        return -1;
492
493
 
493
 
    offset = avio_seek(s->pb, offset, SEEK_SET);
494
 
    return (offset < 0) ? offset : 0;
 
494
    ff_dv_offset_reset(c, offset / c->sys->frame_size);
 
495
    return 0;
495
496
}
496
497
 
497
498
static int dv_read_close(AVFormatContext *s)
537
538
#if CONFIG_DV_DEMUXER
538
539
AVInputFormat ff_dv_demuxer = {
539
540
    .name           = "dv",
540
 
    .long_name      = NULL_IF_CONFIG_SMALL("DV video format"),
 
541
    .long_name      = NULL_IF_CONFIG_SMALL("DV (Digital Video)"),
541
542
    .priv_data_size = sizeof(RawDVContext),
542
543
    .read_probe     = dv_probe,
543
544
    .read_header    = dv_read_header,
544
545
    .read_packet    = dv_read_packet,
545
546
    .read_close     = dv_read_close,
546
547
    .read_seek      = dv_read_seek,
547
 
    .extensions = "dv,dif",
 
548
    .extensions     = "dv,dif",
548
549
};
549
550
#endif