~ubuntu-branches/ubuntu/lucid/ffmpeg/lucid-security

« back to all changes in this revision

Viewing changes to libavformat/gxfenc.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2009-03-13 09:18:28 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20090313091828-n4ktby5eca487uhv
Tags: 3:0.svn20090303-1ubuntu1+unstripped1
merge from ubuntu.jaunty branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include "avformat.h"
24
24
#include "gxf.h"
25
25
#include "riff.h"
 
26
#include "audiointerleave.h"
26
27
 
27
28
#define GXF_AUDIO_PACKET_SIZE 65536
28
29
 
29
30
typedef struct GXFStreamContext {
 
31
    AudioInterleaveContext aic;
30
32
    AVCodecContext *codec;
31
 
    AVFifoBuffer audio_buffer;
32
33
    uint32_t track_type;
33
34
    uint32_t sample_size;
34
35
    uint32_t sample_rate;
42
43
    int pframes;
43
44
    int bframes;
44
45
    int p_per_gop;
45
 
    int b_per_gop;
 
46
    int b_per_i_or_p; ///< number of B frames per I frame or P frame
46
47
    int first_gop_closed;
47
48
    int64_t current_dts;
48
49
    int dts_delay;
49
50
} GXFStreamContext;
50
51
 
51
52
typedef struct GXFContext {
52
 
    uint32_t nb_frames;
 
53
    uint32_t nb_fields;
53
54
    uint32_t material_flags;
54
55
    uint16_t audio_tracks;
55
56
    uint16_t mpeg_tracks;
174
175
        ctx->p_per_gop = ctx->pframes / ctx->iframes;
175
176
        if (ctx->pframes % ctx->iframes)
176
177
            ctx->p_per_gop++;
177
 
        if (ctx->pframes)
178
 
            ctx->b_per_gop = ctx->bframes / ctx->pframes;
 
178
        if (ctx->pframes) {
 
179
            ctx->b_per_i_or_p = ctx->bframes / ctx->pframes;
 
180
            if (ctx->bframes % ctx->pframes)
 
181
                ctx->b_per_i_or_p++;
 
182
        }
179
183
        if (ctx->p_per_gop > 9)
180
184
            ctx->p_per_gop = 9; /* ensure value won't take more than one char */
181
 
        if (ctx->b_per_gop > 9)
182
 
            ctx->b_per_gop = 9; /* ensure value won't take more than one char */
 
185
        if (ctx->b_per_i_or_p > 9)
 
186
            ctx->b_per_i_or_p = 9; /* ensure value won't take more than one char */
183
187
    }
184
188
    if (ctx->codec->height == 512 || ctx->codec->height == 608)
185
189
        starting_line = 7; // VBI
190
194
 
191
195
    size = snprintf(buffer, 1024, "Ver 1\nBr %.6f\nIpg 1\nPpi %d\nBpiop %d\n"
192
196
                    "Pix 0\nCf %d\nCg %d\nSl %d\nnl16 %d\nVi 1\nf1 1\n",
193
 
                    (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_gop,
 
197
                    (float)ctx->codec->bit_rate, ctx->p_per_gop, ctx->b_per_i_or_p,
194
198
                    ctx->codec->pix_fmt == PIX_FMT_YUV422P ? 2 : 1, ctx->first_gop_closed == 1,
195
199
                    starting_line, ctx->codec->height / 16);
196
200
    put_byte(pb, TRACK_MPG_AUX);
292
296
    /* last field */
293
297
    put_byte(pb, MAT_LAST_FIELD);
294
298
    put_byte(pb, 4);
295
 
    put_be32(pb, ctx->nb_frames);
 
299
    put_be32(pb, ctx->nb_fields);
296
300
 
297
301
    /* reserved */
298
302
    put_byte(pb, MAT_MARK_IN);
301
305
 
302
306
    put_byte(pb, MAT_MARK_OUT);
303
307
    put_byte(pb, 4);
304
 
    put_be32(pb, ctx->nb_frames);
 
308
    put_be32(pb, ctx->nb_fields);
305
309
 
306
310
    /* estimated size */
307
311
    put_byte(pb, MAT_SIZE);
361
365
{
362
366
    // XXX drop frame
363
367
    uint32_t timecode =
364
 
        ctx->nb_frames / (ctx->sample_rate * 3600) % 24 << 24 | // hours
365
 
        ctx->nb_frames / (ctx->sample_rate * 60) % 60   << 16 | // minutes
366
 
        ctx->nb_frames / ctx->sample_rate % 60          <<  8 | // seconds
367
 
        ctx->nb_frames % ctx->sample_rate;                    // fields
 
368
        ctx->nb_fields / (ctx->sample_rate * 3600) % 24 << 24 | // hours
 
369
        ctx->nb_fields / (ctx->sample_rate * 60) % 60   << 16 | // minutes
 
370
        ctx->nb_fields / ctx->sample_rate % 60          <<  8 | // seconds
 
371
        ctx->nb_fields % ctx->sample_rate;                    // fields
368
372
 
369
373
    put_le32(pb, ctx->flags);
370
 
    put_le32(pb, ctx->nb_frames); /* length of the longest track */
371
 
    put_le32(pb, ctx->nb_frames); /* length of the shortest track */
 
374
    put_le32(pb, ctx->nb_fields); /* length of the longest track */
 
375
    put_le32(pb, ctx->nb_fields); /* length of the shortest track */
372
376
    put_le32(pb, 0); /* mark in */
373
 
    put_le32(pb, ctx->nb_frames); /* mark out */
 
377
    put_le32(pb, ctx->nb_fields); /* mark out */
374
378
    put_le32(pb, 0); /* timecode mark in */
375
379
    put_le32(pb, timecode); /* timecode mark out */
376
380
    put_le64(pb, ctx->fc->timestamp); /* modification time */
440
444
    put_le32(pb, 3); /* top = 1, bottom = 2, frame = 3, unknown = 0 */
441
445
    put_le32(pb, 1); /* I picture per GOP */
442
446
    put_le32(pb, stream->p_per_gop);
443
 
    put_le32(pb, stream->b_per_gop);
 
447
    put_le32(pb, stream->b_per_i_or_p);
444
448
    if (stream->codec->codec_id == CODEC_ID_MPEG2VIDEO)
445
449
        put_le32(pb, 2);
446
450
    else if (stream->codec->codec_id == CODEC_ID_MPEG1VIDEO)
516
520
        put_le16(pb, sc->media_info);
517
521
        put_le16(pb, 0); /* reserved */
518
522
        put_le16(pb, 0); /* reserved */
519
 
        put_le32(pb, ctx->nb_frames);
 
523
        put_le32(pb, ctx->nb_fields);
520
524
        put_le32(pb, 0); /* attributes rw, ro */
521
525
        put_le32(pb, 0); /* mark in */
522
 
        put_le32(pb, ctx->nb_frames); /* mark out */
 
526
        put_le32(pb, ctx->nb_fields); /* mark out */
523
527
        strncpy(buffer, ES_NAME_PATTERN, path_size);
524
528
        put_buffer(pb, (uint8_t *)buffer, path_size);
525
529
        put_be16(pb, sc->media_info);
587
591
 
588
592
#define GXF_NODELAY -5000
589
593
 
 
594
static const int GXF_samples_per_frame[] = { 32768, 0 };
 
595
 
590
596
static int gxf_write_header(AVFormatContext *s)
591
597
{
592
598
    ByteIOContext *pb = s->pb;
627
633
            sc->fields = -2;
628
634
            gxf->audio_tracks++;
629
635
            gxf->flags |= 0x04000000; /* audio is 16 bit pcm */
630
 
            av_fifo_init(&sc->audio_buffer, 3*GXF_AUDIO_PACKET_SIZE);
631
636
        } else if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
632
637
            /* FIXME check from time_base ? */
633
638
            if (sc->codec->height == 480 || sc->codec->height == 512) { /* NTSC or NTSC+VBI */
670
675
            }
671
676
        }
672
677
    }
 
678
 
 
679
    if (ff_audio_interleave_init(s, GXF_samples_per_frame, (AVRational){ 1, 48000 }) < 0)
 
680
        return -1;
 
681
 
673
682
    gxf_write_map_packet(pb, gxf);
674
683
    //gxf_write_flt_packet(pb, gxf);
675
684
    gxf_write_umf_packet(pb, gxf);
690
699
    ByteIOContext *pb = s->pb;
691
700
    GXFContext *gxf = s->priv_data;
692
701
    int64_t end;
693
 
    int i;
694
702
 
695
 
    for (i = 0; i < s->nb_streams; ++i) {
696
 
        AVStream *st = s->streams[i];
697
 
        if (st->codec->codec_type == CODEC_TYPE_AUDIO)
698
 
            av_fifo_free(&((GXFStreamContext*)st->priv_data)->audio_buffer);
699
 
    }
 
703
    ff_audio_interleave_close(s);
700
704
 
701
705
    gxf_write_eos_packet(pb, gxf);
702
706
    end = url_ftell(pb);
724
728
static int gxf_write_media_preamble(ByteIOContext *pb, GXFContext *ctx, AVPacket *pkt, int size)
725
729
{
726
730
    GXFStreamContext *sc = ctx->fc->streams[pkt->stream_index]->priv_data;
727
 
    int64_t dts = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
 
731
    unsigned field_nb;
 
732
    /* If the video is frame-encoded, the frame numbers shall be represented by
 
733
     * even field numbers.
 
734
     * see SMPTE360M-2004  6.4.2.1.3 Media field number */
 
735
    if (sc->codec->codec_type == CODEC_TYPE_VIDEO) {
 
736
        field_nb = ctx->nb_fields;
 
737
    } else {
 
738
        field_nb = av_rescale_rnd(pkt->dts, ctx->sample_rate, sc->codec->time_base.den, AV_ROUND_UP);
 
739
    }
728
740
 
729
741
    put_byte(pb, sc->media_type);
730
742
    put_byte(pb, sc->index);
731
 
    put_be32(pb, dts);
 
743
    put_be32(pb, field_nb);
732
744
    if (sc->codec->codec_type == CODEC_TYPE_AUDIO) {
733
745
        put_be16(pb, 0);
734
746
        put_be16(pb, size / 2);
750
762
        put_be24(pb, 0);
751
763
    } else
752
764
        put_be32(pb, size);
753
 
    put_be32(pb, dts);
 
765
    put_be32(pb, field_nb);
754
766
    put_byte(pb, 1); /* flags */
755
767
    put_byte(pb, 0); /* reserved */
756
768
    return 16;
772
784
    gxf_write_padding(pb, padding);
773
785
 
774
786
    if (sc->codec->codec_type == CODEC_TYPE_VIDEO)
775
 
        ctx->nb_frames += 2; // count fields
 
787
        ctx->nb_fields += 2; // count fields
776
788
 
777
789
    return updatePacketSize(pb, pos);
778
790
}
786
798
    return 0;
787
799
}
788
800
 
789
 
static int gxf_new_audio_packet(GXFContext *gxf, GXFStreamContext *sc, AVPacket *pkt, int flush)
790
 
{
791
 
    int size = flush ? av_fifo_size(&sc->audio_buffer) : GXF_AUDIO_PACKET_SIZE;
792
 
 
793
 
    if (!size)
794
 
        return 0;
795
 
    av_new_packet(pkt, size);
796
 
    av_fifo_read(&sc->audio_buffer, pkt->data, size);
797
 
    pkt->stream_index = sc->index;
798
 
    pkt->dts = sc->current_dts;
799
 
    sc->current_dts += size / 2; /* we only support 16 bit pcm mono for now */
800
 
    return size;
801
 
}
802
 
 
803
801
static int gxf_interleave_packet(AVFormatContext *s, AVPacket *out, AVPacket *pkt, int flush)
804
802
{
805
 
    GXFContext *gxf = s->priv_data;
806
 
    AVPacket new_pkt;
807
 
    int i;
808
 
 
809
 
    for (i = 0; i < s->nb_streams; i++) {
810
 
        AVStream *st = s->streams[i];
811
 
        GXFStreamContext *sc = st->priv_data;
812
 
        if (st->codec->codec_type == CODEC_TYPE_AUDIO) {
813
 
            if (pkt && pkt->stream_index == i) {
814
 
                av_fifo_generic_write(&sc->audio_buffer, pkt->data, pkt->size, NULL);
815
 
                pkt = NULL;
816
 
            }
817
 
            if (flush || av_fifo_size(&sc->audio_buffer) >= GXF_AUDIO_PACKET_SIZE) {
818
 
                if (!pkt && gxf_new_audio_packet(gxf, sc, &new_pkt, flush) > 0) {
819
 
                    pkt = &new_pkt;
820
 
                    break; /* add pkt right now into list */
821
 
                }
822
 
            }
823
 
        } else if (pkt && pkt->stream_index == i) {
824
 
            if (sc->dts_delay == GXF_NODELAY) /* adjust dts if needed */
825
 
                sc->dts_delay = pkt->dts;
826
 
            pkt->dts -= sc->dts_delay;
827
 
        }
828
 
    }
829
 
    return av_interleave_packet_per_dts(s, out, pkt, flush);
 
803
    return ff_audio_rechunk_interleave(s, out, pkt, flush,
 
804
                               av_interleave_packet_per_dts, ff_interleave_compare_dts);
830
805
}
831
806
 
832
807
AVOutputFormat gxf_muxer = {