⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mpeg.c

📁 F:图像处理资料264264书籍ffmpeg-0.4.9-pre1VideoStream.rar 一个视频解压缩源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
    if (s->is_vcd || s->is_mpeg2)        /* every packet */        s->pack_header_freq = 1;    else        /* every 2 seconds */        s->pack_header_freq = 2 * bitrate / s->packet_size / 8;    /* the above seems to make pack_header_freq zero sometimes */    if (s->pack_header_freq == 0)       s->pack_header_freq = 1;        if (s->is_mpeg2)        /* every 200 packets. Need to look at the spec.  */        s->system_header_freq = s->pack_header_freq * 40;    else if (s->is_vcd)        /* the standard mandates that there are only two system headers           in the whole file: one in the first packet of each stream.           (see standard p. IV-7 and IV-8) */        s->system_header_freq = 0x7fffffff;    else        s->system_header_freq = s->pack_header_freq * 5;        for(i=0;i<ctx->nb_streams;i++) {        stream = ctx->streams[i]->priv_data;        stream->buffer_ptr = 0;        stream->packet_number = 0;        stream->start_pts = AV_NOPTS_VALUE;        stream->start_dts = AV_NOPTS_VALUE;    }    s->system_header_size = get_system_header_size(ctx);    s->last_scr = 0;    return 0; fail:    for(i=0;i<ctx->nb_streams;i++) {        av_free(ctx->streams[i]->priv_data);    }    return -ENOMEM;}static inline void put_timestamp(ByteIOContext *pb, int id, int64_t timestamp){    put_byte(pb,              (id << 4) |              (((timestamp >> 30) & 0x07) << 1) |              1);    put_be16(pb, (uint16_t)((((timestamp >> 15) & 0x7fff) << 1) | 1));    put_be16(pb, (uint16_t)((((timestamp) & 0x7fff) << 1) | 1));}/* return the number of padding bytes that should be inserted into   the multiplexed stream.*/static int get_vcd_padding_size(AVFormatContext *ctx, int64_t pts){    MpegMuxContext *s = ctx->priv_data;    int pad_bytes = 0;    if (s->vcd_padding_bitrate > 0 && pts!=AV_NOPTS_VALUE)    {        int64_t full_pad_bytes;                full_pad_bytes = (int64_t)((s->vcd_padding_bitrate * (pts / 90000.0)) / 8.0);        pad_bytes = (int) (full_pad_bytes - s->vcd_padding_bytes_written);        if (pad_bytes<0)            /* might happen if we have already padded to a later timestamp. This               can occur if another stream has already advanced further.*/            pad_bytes=0;    }    return pad_bytes;}/* return the exact available payload size for the next packet for   stream 'stream_index'. 'pts' and 'dts' are only used to know if   timestamps are needed in the packet header. */static int get_packet_payload_size(AVFormatContext *ctx, int stream_index,                                   int64_t pts, int64_t dts){    MpegMuxContext *s = ctx->priv_data;    int buf_index;    StreamInfo *stream;    stream = ctx->streams[stream_index]->priv_data;    buf_index = 0;    if (((s->packet_number % s->pack_header_freq) == 0)) {        /* pack header size */        if (s->is_mpeg2)             buf_index += 14;        else            buf_index += 12;                if (s->is_vcd) {            /* there is exactly one system header for each stream in a VCD MPEG,               One in the very first video packet and one in the very first               audio packet (see VCD standard p. IV-7 and IV-8).*/                        if (stream->packet_number==0)                /* The system headers refer only to the stream they occur in,                   so they have a constant size.*/                buf_index += 15;        } else {                        if ((s->packet_number % s->system_header_freq) == 0)                buf_index += s->system_header_size;        }    }    if ((s->is_vcd && stream->packet_number==0)        || (s->is_svcd && s->packet_number==0))        /* the first pack of each stream contains only the pack header,           the system header and some padding (see VCD standard p. IV-6)            Add the padding size, so that the actual payload becomes 0.*/        buf_index += s->packet_size - buf_index;    else {        /* packet header size */        buf_index += 6;        if (s->is_mpeg2) {            buf_index += 3;            if (stream->packet_number==0)                buf_index += 3; /* PES extension */            buf_index += 1;    /* obligatory stuffing byte */        }        if (pts != AV_NOPTS_VALUE) {            if (dts != pts)                buf_index += 5 + 5;            else                buf_index += 5;        } else {            if (!s->is_mpeg2)                buf_index++;        }            if (stream->id < 0xc0) {            /* AC3/LPCM private data header */            buf_index += 4;            if (stream->id >= 0xa0) {                int n;                buf_index += 3;                /* NOTE: we round the payload size to an integer number of                   LPCM samples */                n = (s->packet_size - buf_index) % stream->lpcm_align;                if (n)                    buf_index += (stream->lpcm_align - n);            }        }        if (s->is_vcd && stream->id == AUDIO_ID)            /* The VCD standard demands that 20 zero bytes follow               each audio packet (see standard p. IV-8).*/            buf_index+=20;    }    return s->packet_size - buf_index; }/* Write an MPEG padding packet header. */static int put_padding_header(AVFormatContext *ctx,uint8_t* buf, int full_padding_size){    MpegMuxContext *s = ctx->priv_data;    int size = full_padding_size - 6;    /* subtract header length */    buf[0] = (uint8_t)(PADDING_STREAM >> 24);    buf[1] = (uint8_t)(PADDING_STREAM >> 16);    buf[2] = (uint8_t)(PADDING_STREAM >> 8);    buf[3] = (uint8_t)(PADDING_STREAM);    buf[4] = (uint8_t)(size >> 8);    buf[5] = (uint8_t)(size & 0xff);    if (!s->is_mpeg2) {        buf[6] = 0x0f;        return 7;    } else        return 6;}static void put_padding_packet(AVFormatContext *ctx, ByteIOContext *pb,int packet_bytes){    uint8_t buffer[7];    int size, i;        size = put_padding_header(ctx,buffer, packet_bytes);    put_buffer(pb, buffer, size);    packet_bytes -= size;    for(i=0;i<packet_bytes;i++)        put_byte(pb, 0xff);}/* flush the packet on stream stream_index */static void flush_packet(AVFormatContext *ctx, int stream_index,                          int64_t pts, int64_t dts, int64_t scr){    MpegMuxContext *s = ctx->priv_data;    StreamInfo *stream = ctx->streams[stream_index]->priv_data;    uint8_t *buf_ptr;    int size, payload_size, startcode, id, stuffing_size, i, header_len;    int packet_size;    uint8_t buffer[128];    int zero_trail_bytes = 0;    int pad_packet_bytes = 0;    int pes_flags;    int general_pack = 0;  /*"general" pack without data specific to one stream?*/        id = stream->id;    #if 0    printf("packet ID=%2x PTS=%0.3f\n",            id, pts / 90000.0);#endif    buf_ptr = buffer;    if (((s->packet_number % s->pack_header_freq) == 0)) {        /* output pack and systems header if needed */        size = put_pack_header(ctx, buf_ptr, scr);        buf_ptr += size;        if (s->is_vcd) {            /* there is exactly one system header for each stream in a VCD MPEG,               One in the very first video packet and one in the very first               audio packet (see VCD standard p. IV-7 and IV-8).*/                        if (stream->packet_number==0) {                size = put_system_header(ctx, buf_ptr, id);                buf_ptr += size;            }        } else {            if ((s->packet_number % s->system_header_freq) == 0) {                size = put_system_header(ctx, buf_ptr, 0);                buf_ptr += size;            }        }    }    size = buf_ptr - buffer;    put_buffer(&ctx->pb, buffer, size);    packet_size = s->packet_size - size;    if (s->is_vcd && id == AUDIO_ID)        /* The VCD standard demands that 20 zero bytes follow           each audio pack (see standard p. IV-8).*/        zero_trail_bytes += 20;                if ((s->is_vcd && stream->packet_number==0)        || (s->is_svcd && s->packet_number==0)) {        /* for VCD the first pack of each stream contains only the pack header,           the system header and lots of padding (see VCD standard p. IV-6).           In the case of an audio pack, 20 zero bytes are also added at           the end.*/        /* For SVCD we fill the very first pack to increase compatibility with           some DVD players. Not mandated by the standard.*/        if (s->is_svcd)            general_pack = 1;    /* the system header refers to both streams and no stream data*/        pad_packet_bytes = packet_size - zero_trail_bytes;    }    packet_size -= pad_packet_bytes + zero_trail_bytes;    if (packet_size > 0) {        /* packet header size */        packet_size -= 6;                /* packet header */        if (s->is_mpeg2) {            header_len = 3;            if (stream->packet_number==0)                header_len += 3; /* PES extension */            header_len += 1; /* obligatory stuffing byte */        } else {            header_len = 0;        }        if (pts != AV_NOPTS_VALUE) {            if (dts != pts)                header_len += 5 + 5;            else                header_len += 5;        } else {            if (!s->is_mpeg2)                header_len++;        }        payload_size = packet_size - header_len;        if (id < 0xc0) {            startcode = PRIVATE_STREAM_1;            payload_size -= 4;            if (id >= 0xa0)                payload_size -= 3;        } else {            startcode = 0x100 + id;        }        stuffing_size = payload_size - stream->buffer_ptr;        if (stuffing_size < 0)            stuffing_size = 0;        if (stuffing_size > 16) {    /*<=16 for MPEG-1, <=32 for MPEG-2*/            pad_packet_bytes += stuffing_size;            packet_size -= stuffing_size;            payload_size -= stuffing_size;            stuffing_size = 0;        }        put_be32(&ctx->pb, startcode);        put_be16(&ctx->pb, packet_size);                if (!s->is_mpeg2)            for(i=0;i<stuffing_size;i++)                put_byte(&ctx->pb, 0xff);        if (s->is_mpeg2) {            put_byte(&ctx->pb, 0x80); /* mpeg2 id */            pes_flags=0;            if (pts != AV_NOPTS_VALUE) {                pes_flags |= 0x80;                if (dts != pts)                    pes_flags |= 0x40;            }            /* Both the MPEG-2 and the SVCD standards demand that the               P-STD_buffer_size field be included in the first packet of               every stream. (see SVCD standard p. 26 V.2.3.1 and V.2.3.2               and MPEG-2 standard 2.7.7) */            if (stream->packet_number == 0)                pes_flags |= 0x01;            put_byte(&ctx->pb, pes_flags); /* flags */            put_byte(&ctx->pb, header_len - 3 + stuffing_size);            if (pes_flags & 0x80)  /*write pts*/                put_timestamp(&ctx->pb, (pes_flags & 0x40) ? 0x03 : 0x02, pts);            if (pes_flags & 0x40)  /*write dts*/                put_timestamp(&ctx->pb, 0x01, dts);                        if (pes_flags & 0x01) {  /*write pes extension*/                put_byte(&ctx->pb, 0x10); /* flags */                /* P-STD buffer info */                                if (id == AUDIO_ID)                    put_be16(&ctx->pb, 0x4000 | stream->max_buffer_size/128);                else                    put_be16(&ctx->pb, 0x6000 | stream->max_buffer_size/1024);            }        } else {            if (pts != AV_NOPTS_VALUE) {                if (dts != pts) {                    put_timestamp(&ctx->pb, 0x03, pts);                    put_timestamp(&ctx->pb, 0x01, dts);                } else {                    put_timestamp(&ctx->pb, 0x02, pts);                }            } else {                put_byte(&ctx->pb, 0x0f);            }        }        if (s->is_mpeg2) {            /* special stuffing byte that is always written               to prevent accidental generation of start codes. */            put_byte(&ctx->pb, 0xff);            for(i=0;i<stuffing_size;i++)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -