📄 swfenc.c.svn-base
字号:
/* * Flash Compatible Streaming Format muxer * Copyright (c) 2000 Fabrice Bellard. * Copyright (c) 2003 Tinic Uro. * * This file is part of FFmpeg. * * FFmpeg is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * FFmpeg is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with FFmpeg; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */#include "libavcodec/bitstream.h"#include "avformat.h"#include "swf.h"static void put_swf_tag(AVFormatContext *s, int tag){ SWFContext *swf = s->priv_data; ByteIOContext *pb = s->pb; swf->tag_pos = url_ftell(pb); swf->tag = tag; /* reserve some room for the tag */ if (tag & TAG_LONG) { put_le16(pb, 0); put_le32(pb, 0); } else { put_le16(pb, 0); }}static void put_swf_end_tag(AVFormatContext *s){ SWFContext *swf = s->priv_data; ByteIOContext *pb = s->pb; offset_t pos; int tag_len, tag; pos = url_ftell(pb); tag_len = pos - swf->tag_pos - 2; tag = swf->tag; url_fseek(pb, swf->tag_pos, SEEK_SET); if (tag & TAG_LONG) { tag &= ~TAG_LONG; put_le16(pb, (tag << 6) | 0x3f); put_le32(pb, tag_len - 4); } else { assert(tag_len < 0x3f); put_le16(pb, (tag << 6) | tag_len); } url_fseek(pb, pos, SEEK_SET);}static inline void max_nbits(int *nbits_ptr, int val){ int n; if (val == 0) return; val = abs(val); n = 1; while (val != 0) { n++; val >>= 1; } if (n > *nbits_ptr) *nbits_ptr = n;}static void put_swf_rect(ByteIOContext *pb, int xmin, int xmax, int ymin, int ymax){ PutBitContext p; uint8_t buf[256]; int nbits, mask; init_put_bits(&p, buf, sizeof(buf)); nbits = 0; max_nbits(&nbits, xmin); max_nbits(&nbits, xmax); max_nbits(&nbits, ymin); max_nbits(&nbits, ymax); mask = (1 << nbits) - 1; /* rectangle info */ put_bits(&p, 5, nbits); put_bits(&p, nbits, xmin & mask); put_bits(&p, nbits, xmax & mask); put_bits(&p, nbits, ymin & mask); put_bits(&p, nbits, ymax & mask); flush_put_bits(&p); put_buffer(pb, buf, pbBufPtr(&p) - p.buf);}static void put_swf_line_edge(PutBitContext *pb, int dx, int dy){ int nbits, mask; put_bits(pb, 1, 1); /* edge */ put_bits(pb, 1, 1); /* line select */ nbits = 2; max_nbits(&nbits, dx); max_nbits(&nbits, dy); mask = (1 << nbits) - 1; put_bits(pb, 4, nbits - 2); /* 16 bits precision */ if (dx == 0) { put_bits(pb, 1, 0); put_bits(pb, 1, 1); put_bits(pb, nbits, dy & mask); } else if (dy == 0) { put_bits(pb, 1, 0); put_bits(pb, 1, 0); put_bits(pb, nbits, dx & mask); } else { put_bits(pb, 1, 1); put_bits(pb, nbits, dx & mask); put_bits(pb, nbits, dy & mask); }}#define FRAC_BITS 16static void put_swf_matrix(ByteIOContext *pb, int a, int b, int c, int d, int tx, int ty){ PutBitContext p; uint8_t buf[256]; int nbits; init_put_bits(&p, buf, sizeof(buf)); put_bits(&p, 1, 1); /* a, d present */ nbits = 1; max_nbits(&nbits, a); max_nbits(&nbits, d); put_bits(&p, 5, nbits); /* nb bits */ put_bits(&p, nbits, a); put_bits(&p, nbits, d); put_bits(&p, 1, 1); /* b, c present */ nbits = 1; max_nbits(&nbits, c); max_nbits(&nbits, b); put_bits(&p, 5, nbits); /* nb bits */ put_bits(&p, nbits, c); put_bits(&p, nbits, b); nbits = 1; max_nbits(&nbits, tx); max_nbits(&nbits, ty); put_bits(&p, 5, nbits); /* nb bits */ put_bits(&p, nbits, tx); put_bits(&p, nbits, ty); flush_put_bits(&p); put_buffer(pb, buf, pbBufPtr(&p) - p.buf);}static int swf_write_header(AVFormatContext *s){ SWFContext *swf = s->priv_data; ByteIOContext *pb = s->pb; PutBitContext p; uint8_t buf1[256]; int i, width, height, rate, rate_base; int version; swf->sound_samples = 0; swf->swf_frame_number = 0; swf->video_frame_number = 0; for(i=0;i<s->nb_streams;i++) { AVCodecContext *enc = s->streams[i]->codec; if (enc->codec_type == CODEC_TYPE_AUDIO) { if (enc->codec_id == CODEC_ID_MP3) { if (!enc->frame_size) { av_log(s, AV_LOG_ERROR, "audio frame size not set\n"); return -1; } swf->audio_enc = enc; av_fifo_init(&swf->audio_fifo, AUDIO_FIFO_SIZE); } else { av_log(s, AV_LOG_ERROR, "SWF muxer only supports MP3\n"); return -1; } } else { if (enc->codec_id == CODEC_ID_VP6F || enc->codec_id == CODEC_ID_FLV1 || enc->codec_id == CODEC_ID_MJPEG) { swf->video_enc = enc; } else { av_log(s, AV_LOG_ERROR, "SWF muxer only supports VP6, FLV1 and MJPEG\n"); return -1; } } } if (!swf->video_enc) { /* currently, cannot work correctly if audio only */ width = 320; height = 200; rate = 10; rate_base= 1; } else { width = swf->video_enc->width; height = swf->video_enc->height; rate = swf->video_enc->time_base.den; rate_base = swf->video_enc->time_base.num; } if (!swf->audio_enc) swf->samples_per_frame = (44100. * rate_base) / rate; else swf->samples_per_frame = (swf->audio_enc->sample_rate * rate_base) / rate; put_tag(pb, "FWS"); if (!strcmp("avm2", s->oformat->name)) version = 9; else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_VP6F) version = 8; /* version 8 and above support VP6 codec */ else if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_FLV1) version = 6; /* version 6 and above support FLV1 codec */ else version = 4; /* version 4 for mpeg audio support */ put_byte(pb, version); put_le32(pb, DUMMY_FILE_SIZE); /* dummy size (will be patched if not streamed) */ put_swf_rect(pb, 0, width * 20, 0, height * 20); put_le16(pb, (rate * 256) / rate_base); /* frame rate */ swf->duration_pos = url_ftell(pb); put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */ /* avm2/swf v9 (also v8?) files require a file attribute tag */ if (version == 9) { put_swf_tag(s, TAG_FILEATTRIBUTES); put_le32(pb, 1<<3); /* set ActionScript v3/AVM2 flag */ put_swf_end_tag(s); } /* define a shape with the jpeg inside */ if (swf->video_enc && swf->video_enc->codec_id == CODEC_ID_MJPEG) { put_swf_tag(s, TAG_DEFINESHAPE); put_le16(pb, SHAPE_ID); /* ID of shape */ /* bounding rectangle */ put_swf_rect(pb, 0, width, 0, height); /* style info */ put_byte(pb, 1); /* one fill style */ put_byte(pb, 0x41); /* clipped bitmap fill */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -