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

📄 gif.c.svn-base

📁 mediastreamer2是开源的网络传输媒体流的库
💻 SVN-BASE
📖 第 1 页 / 共 2 页
字号:
                                         (three bytes of data to follow)                byte  16       : 1 (hex 0x01)                bytes 17 to 18 : 0 to 65535, an unsigned integer in                                         lo-hi byte format. This indicate the                                         number of iterations the loop should                                         be executed.                bytes 19       : 0 (hex 0x00) a Data Sub-block Terminator        */    /* application extension header */#ifdef GIF_ADD_APP_HEADER    if (loop_count >= 0 && loop_count <= 65535) {    put_byte(pb, 0x21);    put_byte(pb, 0xff);    put_byte(pb, 0x0b);        put_tag(pb, "NETSCAPE2.0");  // bytes 4 to 14        put_byte(pb, 0x03); // byte 15        put_byte(pb, 0x01); // byte 16        put_le16(pb, (uint16_t)loop_count);        put_byte(pb, 0x00); // byte 19    }#endif    return 0;}/* this is maybe slow, but allows for extensions */static inline unsigned char gif_clut_index(uint8_t r, uint8_t g, uint8_t b){    return ((((r)/47)%6)*6*6+(((g)/47)%6)*6+(((b)/47)%6));}static int gif_image_write_image(ByteIOContext *pb,                                 int x1, int y1, int width, int height,                                 const uint8_t *buf, int linesize, int pix_fmt){    PutBitContext p;    uint8_t buffer[200]; /* 100 * 9 / 8 = 113 */    int i, left, w, v;    const uint8_t *ptr;    /* image block */    put_byte(pb, 0x2c);    put_le16(pb, x1);    put_le16(pb, y1);    put_le16(pb, width);    put_le16(pb, height);    put_byte(pb, 0x00); /* flags */    /* no local clut */    put_byte(pb, 0x08);    left= width * height;    init_put_bits(&p, buffer, 130);/* * the thing here is the bitstream is written as little packets, with a size byte before * but it's still the same bitstream between packets (no flush !) */    ptr = buf;    w = width;    while(left>0) {        gif_put_bits_rev(&p, 9, 0x0100); /* clear code */        for(i=(left<GIF_CHUNKS)?left:GIF_CHUNKS;i;i--) {            if (pix_fmt == PIX_FMT_RGB24) {                v = gif_clut_index(ptr[0], ptr[1], ptr[2]);                ptr+=3;            } else {                v = *ptr++;            }            gif_put_bits_rev(&p, 9, v);            if (--w == 0) {                w = width;                buf += linesize;                ptr = buf;            }        }        if(left<=GIF_CHUNKS) {            gif_put_bits_rev(&p, 9, 0x101); /* end of stream */            gif_flush_put_bits_rev(&p);        }        if(pbBufPtr(&p) - p.buf > 0) {            put_byte(pb, pbBufPtr(&p) - p.buf); /* byte count of the packet */            put_buffer(pb, p.buf, pbBufPtr(&p) - p.buf); /* the actual buffer */            p.buf_ptr = p.buf; /* dequeue the bytes off the bitstream */        }        left-=GIF_CHUNKS;    }    put_byte(pb, 0x00); /* end of image block */    return 0;}typedef struct {    int64_t time, file_time;    uint8_t buffer[100]; /* data chunks */} GIFContext;static int gif_write_header(AVFormatContext *s){    GIFContext *gif = s->priv_data;    ByteIOContext *pb = s->pb;    AVCodecContext *enc, *video_enc;    int i, width, height, loop_count /*, rate*/;/* XXX: do we reject audio streams or just ignore them ?    if(s->nb_streams > 1)        return -1;*/    gif->time = 0;    gif->file_time = 0;    video_enc = NULL;    for(i=0;i<s->nb_streams;i++) {        enc = s->streams[i]->codec;        if (enc->codec_type != CODEC_TYPE_AUDIO)            video_enc = enc;    }    if (!video_enc) {        av_free(gif);        return -1;    } else {        width = video_enc->width;        height = video_enc->height;        loop_count = s->loop_output;//        rate = video_enc->time_base.den;    }    if (video_enc->pix_fmt != PIX_FMT_RGB24) {        av_log(s, AV_LOG_ERROR, "ERROR: gif only handles the rgb24 pixel format. Use -pix_fmt rgb24.\n");        return AVERROR(EIO);    }    gif_image_write_header(pb, width, height, loop_count, NULL);    put_flush_packet(s->pb);    return 0;}static int gif_write_video(AVFormatContext *s,                           AVCodecContext *enc, const uint8_t *buf, int size){    ByteIOContext *pb = s->pb;    GIFContext *gif = s->priv_data;    int jiffies;    int64_t delay;    /* graphic control extension block */    put_byte(pb, 0x21);    put_byte(pb, 0xf9);    put_byte(pb, 0x04); /* block size */    put_byte(pb, 0x04); /* flags */    /* 1 jiffy is 1/70 s */    /* the delay_time field indicates the number of jiffies - 1 */    delay = gif->file_time - gif->time;    /* XXX: should use delay, in order to be more accurate */    /* instead of using the same rounded value each time */    /* XXX: don't even remember if I really use it for now */    jiffies = (70*enc->time_base.num/enc->time_base.den) - 1;    put_le16(pb, jiffies);    put_byte(pb, 0x1f); /* transparent color index */    put_byte(pb, 0x00);    gif_image_write_image(pb, 0, 0, enc->width, enc->height,                          buf, enc->width * 3, PIX_FMT_RGB24);    put_flush_packet(s->pb);    return 0;}static int gif_write_packet(AVFormatContext *s, AVPacket *pkt){    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;    if (codec->codec_type == CODEC_TYPE_AUDIO)        return 0; /* just ignore audio */    else        return gif_write_video(s, codec, pkt->data, pkt->size);}static int gif_write_trailer(AVFormatContext *s){    ByteIOContext *pb = s->pb;    put_byte(pb, 0x3b);    put_flush_packet(s->pb);    return 0;}AVOutputFormat gif_muxer = {    "gif",    "GIF Animation",    "image/gif",    "gif",    sizeof(GIFContext),    CODEC_ID_NONE,    CODEC_ID_RAWVIDEO,    gif_write_header,    gif_write_packet,    gif_write_trailer,};

⌨️ 快捷键说明

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