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

📄 swf.c

📁 mediastreamer2是开源的网络传输媒体流的库
💻 C
📖 第 1 页 / 共 2 页
字号:
        put_byte(s->pb, v);        put_le16(s->pb, swf->samples_per_frame);  /* avg samples per frame */        put_le16(s->pb, 0);        put_swf_end_tag(s);    }    put_flush_packet(s->pb);    return 0;}static int swf_write_video(AVFormatContext *s,                           AVCodecContext *enc, const uint8_t *buf, int size){    SWFContext *swf = s->priv_data;    ByteIOContext *pb = s->pb;    /* Flash Player limit */    if (swf->swf_frame_number == 16000) {        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");    }    if (swf->video_type == CODEC_ID_VP6F ||        swf->video_type == CODEC_ID_FLV1) {        if (swf->video_frame_number == 0) {            /* create a new video object */            put_swf_tag(s, TAG_VIDEOSTREAM);            put_le16(pb, VIDEO_ID);            put_le16(pb, 15000); /* hard flash player limit */            put_le16(pb, enc->width);            put_le16(pb, enc->height);            put_byte(pb, 0);            put_byte(pb,codec_get_tag(swf_codec_tags,swf->video_type));            put_swf_end_tag(s);            /* place the video object for the first time */            put_swf_tag(s, TAG_PLACEOBJECT2);            put_byte(pb, 0x36);            put_le16(pb, 1);            put_le16(pb, VIDEO_ID);            put_swf_matrix(pb, 1 << FRAC_BITS, 0, 0, 1 << FRAC_BITS, 0, 0);            put_le16(pb, swf->video_frame_number);            put_byte(pb, 'v');            put_byte(pb, 'i');            put_byte(pb, 'd');            put_byte(pb, 'e');            put_byte(pb, 'o');            put_byte(pb, 0x00);            put_swf_end_tag(s);        } else {            /* mark the character for update */            put_swf_tag(s, TAG_PLACEOBJECT2);            put_byte(pb, 0x11);            put_le16(pb, 1);            put_le16(pb, swf->video_frame_number);            put_swf_end_tag(s);        }        /* set video frame data */        put_swf_tag(s, TAG_VIDEOFRAME | TAG_LONG);        put_le16(pb, VIDEO_ID);        put_le16(pb, swf->video_frame_number++);        put_buffer(pb, buf, size);        put_swf_end_tag(s);    } else if (swf->video_type == CODEC_ID_MJPEG) {        if (swf->swf_frame_number > 0) {            /* remove the shape */            put_swf_tag(s, TAG_REMOVEOBJECT);            put_le16(pb, SHAPE_ID); /* shape ID */            put_le16(pb, 1); /* depth */            put_swf_end_tag(s);            /* free the bitmap */            put_swf_tag(s, TAG_FREECHARACTER);            put_le16(pb, BITMAP_ID);            put_swf_end_tag(s);        }        put_swf_tag(s, TAG_JPEG2 | TAG_LONG);        put_le16(pb, BITMAP_ID); /* ID of the image */        /* a dummy jpeg header seems to be required */        put_byte(pb, 0xff);        put_byte(pb, 0xd8);        put_byte(pb, 0xff);        put_byte(pb, 0xd9);        /* write the jpeg image */        put_buffer(pb, buf, size);        put_swf_end_tag(s);        /* draw the shape */        put_swf_tag(s, TAG_PLACEOBJECT);        put_le16(pb, SHAPE_ID); /* shape ID */        put_le16(pb, 1); /* depth */        put_swf_matrix(pb, 20 << FRAC_BITS, 0, 0, 20 << FRAC_BITS, 0, 0);        put_swf_end_tag(s);    } else {        /* invalid codec */    }    swf->swf_frame_number ++;    /* streaming sound always should be placed just before showframe tags */    if (swf->audio_type && swf->audio_in_pos) {        put_swf_tag(s, TAG_STREAMBLOCK | TAG_LONG);        put_le16(pb, swf->sound_samples);        put_le16(pb, 0); // seek samples        put_buffer(pb, swf->audio_fifo, swf->audio_in_pos);        put_swf_end_tag(s);        /* update FIFO */        swf->sound_samples = 0;        swf->audio_in_pos = 0;    }    /* output the frame */    put_swf_tag(s, TAG_SHOWFRAME);    put_swf_end_tag(s);    put_flush_packet(s->pb);    return 0;}static int swf_write_audio(AVFormatContext *s,                           AVCodecContext *enc, const uint8_t *buf, int size){    SWFContext *swf = s->priv_data;    /* Flash Player limit */    if (swf->swf_frame_number == 16000) {        av_log(enc, AV_LOG_INFO, "warning: Flash Player limit of 16000 frames reached\n");    }    if (swf->audio_in_pos + size >= AUDIO_FIFO_SIZE) {        av_log(s, AV_LOG_ERROR, "audio fifo too small to mux audio essence\n");        return -1;    }    memcpy(swf->audio_fifo +  swf->audio_in_pos, buf, size);    swf->audio_in_pos += size;    swf->sound_samples += enc->frame_size;    /* if audio only stream make sure we add swf frames */    if (swf->video_type == 0) {        swf_write_video(s, enc, 0, 0);    }    return 0;}static int swf_write_packet(AVFormatContext *s, AVPacket *pkt){    AVCodecContext *codec = s->streams[pkt->stream_index]->codec;    if (codec->codec_type == CODEC_TYPE_AUDIO)        return swf_write_audio(s, codec, pkt->data, pkt->size);    else        return swf_write_video(s, codec, pkt->data, pkt->size);}static int swf_write_trailer(AVFormatContext *s){    SWFContext *swf = s->priv_data;    ByteIOContext *pb = s->pb;    AVCodecContext *enc, *video_enc;    int file_size, i;    video_enc = NULL;    for(i=0;i<s->nb_streams;i++) {        enc = s->streams[i]->codec;        if (enc->codec_type == CODEC_TYPE_VIDEO)            video_enc = enc;    }    put_swf_tag(s, TAG_END);    put_swf_end_tag(s);    put_flush_packet(s->pb);    /* patch file size and number of frames if not streamed */    if (!url_is_streamed(s->pb) && video_enc) {        file_size = url_ftell(pb);        url_fseek(pb, 4, SEEK_SET);        put_le32(pb, file_size);        url_fseek(pb, swf->duration_pos, SEEK_SET);        put_le16(pb, video_enc->frame_number);        url_fseek(pb, file_size, SEEK_SET);    }    return 0;}#endif //CONFIG_MUXERS/*********************************************//* Extract FLV encoded frame and MP3 from swf   Note that the detection of the real frame   is inaccurate at this point as it can be   quite tricky to determine, you almost certainly   will get a bad audio/video sync */static int get_swf_tag(ByteIOContext *pb, int *len_ptr){    int tag, len;    if (url_feof(pb))        return -1;    tag = get_le16(pb);    len = tag & 0x3f;    tag = tag >> 6;    if (len == 0x3f) {        len = get_le32(pb);    }//    av_log(NULL, AV_LOG_DEBUG, "Tag: %d - Len: %d\n", tag, len);    *len_ptr = len;    return tag;}static int swf_probe(AVProbeData *p){    /* check file header */    if ((p->buf[0] == 'F' || p->buf[0] == 'C') && p->buf[1] == 'W' &&        p->buf[2] == 'S')        return AVPROBE_SCORE_MAX;    else        return 0;}static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap){    SWFContext *swf = s->priv_data;    ByteIOContext *pb = s->pb;    int nbits, len, tag;    tag = get_be32(pb) & 0xffffff00;    if (tag == MKBETAG('C', 'W', 'S', 0)) {        av_log(s, AV_LOG_ERROR, "Compressed SWF format not supported\n");        return AVERROR(EIO);    }    if (tag != MKBETAG('F', 'W', 'S', 0))        return AVERROR(EIO);    get_le32(pb);    /* skip rectangle size */    nbits = get_byte(pb) >> 3;    len = (4 * nbits - 3 + 7) / 8;    url_fskip(pb, len);    swf->frame_rate = get_le16(pb); /* 8.8 fixed */    get_le16(pb); /* frame count */    swf->samples_per_frame = 0;    s->ctx_flags |= AVFMTCTX_NOHEADER;    return 0;}static int swf_read_packet(AVFormatContext *s, AVPacket *pkt){    SWFContext *swf = s->priv_data;    ByteIOContext *pb = s->pb;    AVStream *vst = NULL, *ast = NULL, *st = 0;    int tag, len, i, frame, v;    for(;;) {        tag = get_swf_tag(pb, &len);        if (tag < 0)            return AVERROR(EIO);        if (tag == TAG_VIDEOSTREAM && !vst) {            int ch_id = get_le16(pb);            get_le16(pb);            get_le16(pb);            get_le16(pb);            get_byte(pb);            /* Check for FLV1 */            vst = av_new_stream(s, ch_id);            if (!vst)                return -1;            vst->codec->codec_type = CODEC_TYPE_VIDEO;            vst->codec->codec_id = codec_get_id(swf_codec_tags, get_byte(pb));            av_set_pts_info(vst, 64, 256, swf->frame_rate);            vst->codec->time_base = (AVRational){ 256, swf->frame_rate };            len -= 10;        } else if ((tag == TAG_STREAMHEAD || tag == TAG_STREAMHEAD2) && !ast) {            /* streaming found */            int sample_rate_code;            get_byte(pb);            v = get_byte(pb);            swf->samples_per_frame = get_le16(pb);            ast = av_new_stream(s, -1); /* -1 to avoid clash with video stream ch_id */            if (!ast)                return -1;            swf->audio_stream_index = ast->index;            ast->codec->channels = 1 + (v&1);            ast->codec->codec_type = CODEC_TYPE_AUDIO;            ast->codec->codec_id = codec_get_id(swf_audio_codec_tags, (v>>4) & 15);            ast->need_parsing = AVSTREAM_PARSE_FULL;            sample_rate_code= (v>>2) & 3;            if (!sample_rate_code)                return AVERROR(EIO);            ast->codec->sample_rate = 11025 << (sample_rate_code-1);            av_set_pts_info(ast, 64, 1, ast->codec->sample_rate);            len -= 4;        } else if (tag == TAG_VIDEOFRAME) {            int ch_id = get_le16(pb);            len -= 2;            for(i=0; i<s->nb_streams; i++) {                st = s->streams[i];                if (st->codec->codec_type == CODEC_TYPE_VIDEO && st->id == ch_id) {                    frame = get_le16(pb);                    av_get_packet(pb, pkt, len-2);                    pkt->pts = frame;                    pkt->stream_index = st->index;                    return pkt->size;                }            }        } else if (tag == TAG_STREAMBLOCK) {            st = s->streams[swf->audio_stream_index];            if (st->codec->codec_id == CODEC_ID_MP3) {                url_fskip(pb, 4);                av_get_packet(pb, pkt, len-4);            } else { // ADPCM, PCM                av_get_packet(pb, pkt, len);            }            pkt->stream_index = st->index;            return pkt->size;        } else if (tag == TAG_JPEG2) {            for (i=0; i<s->nb_streams; i++) {                st = s->streams[i];                if (st->id == -2)                    break;            }            if (i == s->nb_streams) {                vst = av_new_stream(s, -2); /* -2 to avoid clash with video stream and audio stream */                if (!vst)                    return -1;                vst->codec->codec_type = CODEC_TYPE_VIDEO;                vst->codec->codec_id = CODEC_ID_MJPEG;                av_set_pts_info(vst, 64, 256, swf->frame_rate);                vst->codec->time_base = (AVRational){ 256, swf->frame_rate };                st = vst;            }            get_le16(pb); /* BITMAP_ID */            av_new_packet(pkt, len-2);            get_buffer(pb, pkt->data, 4);            if (AV_RB32(pkt->data) == 0xffd8ffd9 ||                AV_RB32(pkt->data) == 0xffd9ffd8) {                /* old SWF files containing SOI/EOI as data start */                /* files created by swink have reversed tag */                pkt->size -= 4;                get_buffer(pb, pkt->data, pkt->size);            } else {                get_buffer(pb, pkt->data + 4, pkt->size - 4);            }            pkt->stream_index = st->index;            return pkt->size;        }        url_fskip(pb, len);    }    return 0;}static int swf_read_close(AVFormatContext *s){    return 0;}#ifdef CONFIG_SWF_DEMUXERAVInputFormat swf_demuxer = {    "swf",    "Flash format",    sizeof(SWFContext),    swf_probe,    swf_read_header,    swf_read_packet,    swf_read_close,};#endif#ifdef CONFIG_SWF_MUXERAVOutputFormat swf_muxer = {    "swf",    "Flash format",    "application/x-shockwave-flash",    "swf",    sizeof(SWFContext),    CODEC_ID_MP3,    CODEC_ID_FLV1,    swf_write_header,    swf_write_packet,    swf_write_trailer,};#endif#ifdef CONFIG_AVM2_MUXERAVOutputFormat avm2_muxer = {    "avm2",    "Flash 9 (AVM2) format",    "application/x-shockwave-flash",    NULL,    sizeof(SWFContext),    CODEC_ID_MP3,    CODEC_ID_FLV1,    swf_write_header,    swf_write_packet,    swf_write_trailer,};#endif

⌨️ 快捷键说明

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