]> git.sesse.net Git - ffmpeg/blobdiff - libavformat/swf.c
RFC 2 stage: First feedback from review comments
[ffmpeg] / libavformat / swf.c
index 4d9299f745ee3042205feb3a8753c0550d38ad04..6029e36783a80e5bac1cd272885a59cd50bd0e5e 100644 (file)
@@ -3,22 +3,25 @@
  * Copyright (c) 2000 Fabrice Bellard.
  * Copyright (c) 2003 Tinic Uro.
  *
- * This library is free software; you can redistribute it and/or
+ * 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 of the License, or (at your option) any later version.
+ * version 2.1 of the License, or (at your option) any later version.
  *
- * This library is distributed in the hope that it will be useful,
+ * 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 this library; if not, write to the Free Software
+ * License along with FFmpeg; if not, write to the Free Software
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
  */
 #include "avformat.h"
 #include "bitstream.h"
+#include "riff.h"    /* for CodecTag */
 
 /* should have a generic way to indicate probable size */
 #define DUMMY_FILE_SIZE   (100 * 1024 * 1024)
@@ -45,8 +48,6 @@
 #define FLAG_SETFILL0    0x02
 #define FLAG_SETFILL1    0x04
 
-#define SWF_VIDEO_CODEC_FLV1    0x02
-
 #define AUDIO_FIFO_SIZE 65536
 
 /* character id used */
@@ -80,6 +81,12 @@ typedef struct {
     int audio_type;
 } SWFContext;
 
+static const CodecTag swf_codec_tags[] = {
+    {CODEC_ID_FLV1, 0x02},
+    {CODEC_ID_VP6F, 0x04},
+    {0, 0},
+};
+
 static const int sSampleRates[3][4] = {
     {44100, 48000, 32000, 0},
     {22050, 24000, 16000, 0},
@@ -328,10 +335,12 @@ static int swf_write_header(AVFormatContext *s)
         if (enc->codec_type == CODEC_TYPE_AUDIO)
             audio_enc = enc;
         else {
-            if ( enc->codec_id == CODEC_ID_FLV1 || enc->codec_id == CODEC_ID_MJPEG ) {
+            if ( enc->codec_id == CODEC_ID_VP6F ||
+                 enc->codec_id == CODEC_ID_FLV1 ||
+                 enc->codec_id == CODEC_ID_MJPEG ) {
                 video_enc = enc;
             } else {
-                av_log(enc, AV_LOG_ERROR, "SWF only supports FLV1 and MJPEG\n");
+                av_log(enc, AV_LOG_ERROR, "SWF only supports VP6, FLV1 and MJPEG\n");
                 return -1;
             }
         }
@@ -361,7 +370,9 @@ static int swf_write_header(AVFormatContext *s)
     }
 
     put_tag(pb, "FWS");
-    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
+    if ( video_enc && video_enc->codec_id == CODEC_ID_VP6F ) {
+        put_byte(pb, 8); /* version (version 8 and above support VP6 codec) */
+    } else if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
         put_byte(pb, 6); /* version (version 6 and above support FLV1 codec) */
     } else {
         put_byte(pb, 4); /* version (should use 4 for mpeg audio support) */
@@ -375,7 +386,8 @@ static int swf_write_header(AVFormatContext *s)
     put_le16(pb, (uint16_t)(DUMMY_DURATION * (int64_t)rate / rate_base)); /* frame count */
 
     /* define a shape with the jpeg inside */
-    if ( video_enc && video_enc->codec_id == CODEC_ID_FLV1 ) {
+    if ( video_enc && (video_enc->codec_id == CODEC_ID_VP6F ||
+                       video_enc->codec_id == CODEC_ID_FLV1 )) {
     } else if ( video_enc && video_enc->codec_id == CODEC_ID_MJPEG ) {
         put_swf_tag(s, TAG_DEFINESHAPE);
 
@@ -438,6 +450,7 @@ static int swf_write_header(AVFormatContext *s)
             break;
         default:
             /* not supported */
+            av_log(s, AV_LOG_ERROR, "swf doesnt support that sample rate, choose from (44100, 22050, 11025)\n");
             av_free(swf->audio_fifo);
             av_free(swf);
             return -1;
@@ -512,7 +525,8 @@ retry_swf_audio_packet:
         }
     }
 
-            if ( swf->video_type == CODEC_ID_FLV1 ) {
+            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);
@@ -521,7 +535,7 @@ retry_swf_audio_packet:
                     put_le16(pb, enc->width);
                     put_le16(pb, enc->height);
                     put_byte(pb, 0);
-                    put_byte(pb, SWF_VIDEO_CODEC_FLV1);
+                    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 */
@@ -784,18 +798,20 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
             return AVERROR_IO;
         }
         if ( tag == TAG_VIDEOSTREAM && !vst) {
+            int codec_id;
             swf->ch_id = get_le16(pb);
             get_le16(pb);
             get_le16(pb);
             get_le16(pb);
             get_byte(pb);
             /* Check for FLV1 */
-            if ( get_byte(pb) == SWF_VIDEO_CODEC_FLV1 ) {
+            codec_id = codec_get_id(swf_codec_tags, get_byte(pb));
+            if ( codec_id ) {
                 vst = av_new_stream(s, 0);
                 av_set_pts_info(vst, 24, 1, 1000); /* 24 bit pts in ms */
 
                 vst->codec->codec_type = CODEC_TYPE_VIDEO;
-                vst->codec->codec_id = CODEC_ID_FLV1;
+                vst->codec->codec_id = codec_id;
                 if ( swf->samples_per_frame ) {
                     vst->codec->time_base.den = 1000. / swf->ms_per_frame;
                     vst->codec->time_base.num = 1;
@@ -814,9 +830,9 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                     get_le16(pb);
                 }
                 ast = av_new_stream(s, 1);
-                av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
                 if (!ast)
                     return -ENOMEM;
+                av_set_pts_info(ast, 24, 1, 1000); /* 24 bit pts in ms */
 
                 if (v & 0x01)
                     ast->codec->channels = 2;
@@ -839,6 +855,7 @@ static int swf_read_header(AVFormatContext *s, AVFormatParameters *ap)
                 }
                 ast->codec->codec_type = CODEC_TYPE_AUDIO;
                 ast->codec->codec_id = CODEC_ID_MP3;
+                ast->need_parsing = 1;
             }
         } else {
             url_fskip(pb, len);
@@ -881,7 +898,8 @@ static int swf_read_packet(AVFormatContext *s, AVPacket *pkt)
             for( i=0; i<s->nb_streams; i++ ) {
                 st = s->streams[i];
                 if (st->id == 1) {
-                    av_get_packet(pb, pkt, len);
+                    url_fskip(pb, 4);
+                    av_get_packet(pb, pkt, len-4);
                     pkt->stream_index = st->index;
                     return pkt->size;
                 }
@@ -899,7 +917,8 @@ static int swf_read_close(AVFormatContext *s)
      return 0;
 }
 
-static AVInputFormat swf_iformat = {
+#ifdef CONFIG_SWF_DEMUXER
+AVInputFormat swf_demuxer = {
     "swf",
     "Flash format",
     sizeof(SWFContext),
@@ -908,9 +927,9 @@ static AVInputFormat swf_iformat = {
     swf_read_packet,
     swf_read_close,
 };
-
-#ifdef CONFIG_MUXERS
-static AVOutputFormat swf_oformat = {
+#endif
+#ifdef CONFIG_SWF_MUXER
+AVOutputFormat swf_muxer = {
     "swf",
     "Flash format",
     "application/x-shockwave-flash",
@@ -922,13 +941,4 @@ static AVOutputFormat swf_oformat = {
     swf_write_packet,
     swf_write_trailer,
 };
-#endif //CONFIG_MUXERS
-
-int swf_init(void)
-{
-    av_register_input_format(&swf_iformat);
-#ifdef CONFIG_MUXERS
-    av_register_output_format(&swf_oformat);
-#endif //CONFIG_MUXERS
-    return 0;
-}
+#endif