Browse code

activated 'raw stream copy' feature (use -acodec copy or -vcodec copy)

Originally committed as revision 1026 to svn://svn.ffmpeg.org/ffmpeg/trunk

Fabrice Bellard authored on 2002/10/11 18:19:34
Showing 1 changed files
... ...
@@ -143,6 +143,8 @@ static int do_vstats = 0;
143 143
 static int mpeg_vcd = 0;
144 144
 static int do_pass = 0;
145 145
 static char *pass_logfilename = NULL;
146
+static int audio_stream_copy = 0;
147
+static int video_stream_copy = 0;
146 148
 
147 149
 #define DEFAULT_PASS_LOGFILENAME "ffmpeg2pass"
148 150
 
... ...
@@ -744,17 +746,6 @@ static int av_encode(AVFormatContext **output_files,
744 744
         }
745 745
     }
746 746
 
747
-    /* dump the stream mapping */
748
-    fprintf(stderr, "Stream mapping:\n");
749
-    for(i=0;i<nb_ostreams;i++) {
750
-        ost = ost_table[i];
751
-        fprintf(stderr, "  Stream #%d.%d -> #%d.%d\n",
752
-                ist_table[ost->source_index]->file_index,
753
-                ist_table[ost->source_index]->index,
754
-                ost->file_index, 
755
-                ost->index);
756
-    }
757
-
758 747
     /* for each output stream, we compute the right encoding parameters */
759 748
     for(i=0;i<nb_ostreams;i++) {
760 749
         ost = ost_table[i];
... ...
@@ -763,24 +754,31 @@ static int av_encode(AVFormatContext **output_files,
763 763
         codec = &ost->st->codec;
764 764
         icodec = &ist->st->codec;
765 765
 
766
-        switch(codec->codec_type) {
767
-        case CODEC_TYPE_AUDIO:
768
-            /* check if same codec with same parameters. If so, no
769
-               reencoding is needed */
770
-            if (codec->codec_id == icodec->codec_id &&
771
-                codec->bit_rate == icodec->bit_rate &&
772
-                codec->sample_rate == icodec->sample_rate &&
773
-                codec->channels == icodec->channels) {
774
-                /* no reencoding */
775
-                /* use the same frame size */
776
-                codec->frame_size = icodec->frame_size;
777
-                //codec->frame_size = 8*icodec->sample_rate*icodec->frame_size/
778
-                //                    icodec->bit_rate;
779
-                //fprintf(stderr,"\nFrame size: %d", codec->frame_size);
780
-            } else {
766
+        if (ost->st->stream_copy) {
767
+            /* if stream_copy is selected, no need to decode or encode */
768
+            codec->codec_id = icodec->codec_id;
769
+            codec->codec_type = icodec->codec_type;
770
+            codec->codec_tag = icodec->codec_tag;
771
+            codec->bit_rate = icodec->bit_rate;
772
+            switch(codec->codec_type) {
773
+            case CODEC_TYPE_AUDIO:
774
+                codec->sample_rate = icodec->sample_rate;
775
+                codec->channels = icodec->channels;
776
+                break;
777
+            case CODEC_TYPE_VIDEO:
778
+                codec->frame_rate = icodec->frame_rate;
779
+                codec->width = icodec->width;
780
+                codec->height = icodec->height;
781
+                break;
782
+            default:
783
+                av_abort();
784
+            }
785
+        } else {
786
+            switch(codec->codec_type) {
787
+            case CODEC_TYPE_AUDIO:
781 788
                 if (fifo_init(&ost->fifo, 2 * MAX_AUDIO_PACKET_SIZE))
782 789
                     goto fail;
783
-
790
+                
784 791
                 if (codec->channels == icodec->channels &&
785 792
                     codec->sample_rate == icodec->sample_rate) {
786 793
                     ost->audio_resample = 0;
... ...
@@ -810,18 +808,8 @@ static int av_encode(AVFormatContext **output_files,
810 810
                 }
811 811
                 ist->decoding_needed = 1;
812 812
                 ost->encoding_needed = 1;
813
-            }
814
-            break;
815
-        case CODEC_TYPE_VIDEO:
816
-            /* check if same codec with same parameters. If so, no
817
-               reencoding is needed */
818
-            if (codec->codec_id == icodec->codec_id &&
819
-                codec->bit_rate == icodec->bit_rate &&
820
-                codec->frame_rate == icodec->frame_rate &&
821
-                codec->width == icodec->width &&
822
-                codec->height == icodec->height) {
823
-                /* no reencoding */
824
-            } else {
813
+                break;
814
+            case CODEC_TYPE_VIDEO:
825 815
                 if (codec->width == icodec->width &&
826 816
                     codec->height == icodec->height) {
827 817
                     ost->video_resample = 0;
... ...
@@ -846,52 +834,69 @@ static int av_encode(AVFormatContext **output_files,
846 846
                 }
847 847
                 ost->encoding_needed = 1;
848 848
                 ist->decoding_needed = 1;
849
+                break;
850
+            default:
851
+                av_abort();
849 852
             }
850
-            break;
851
-        default:
852
-            av_abort();
853
-        }
854
-        /* two pass mode */
855
-        if (ost->encoding_needed && 
856
-            (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
857
-            char logfilename[1024];
858
-            FILE *f;
859
-            int size;
860
-            char *logbuffer;
861
-            
862
-            snprintf(logfilename, sizeof(logfilename), "%s-%d.log", 
863
-                     pass_logfilename ? 
864
-                     pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
865
-            if (codec->flags & CODEC_FLAG_PASS1) {
866
-                f = fopen(logfilename, "w");
867
-                if (!f) {
868
-                    perror(logfilename);
869
-                    exit(1);
870
-                }
871
-                ost->logfile = f;
872
-            } else {
873
-                /* read the log file */
874
-                f = fopen(logfilename, "r");
875
-                if (!f) {
876
-                    perror(logfilename);
877
-                    exit(1);
878
-                }
879
-                fseek(f, 0, SEEK_END);
880
-                size = ftell(f);
881
-                fseek(f, 0, SEEK_SET);
882
-                logbuffer = av_malloc(size + 1);
883
-                if (!logbuffer) {
884
-                    fprintf(stderr, "Could not allocate log buffer\n");
885
-                    exit(1);
853
+            /* two pass mode */
854
+            if (ost->encoding_needed && 
855
+                (codec->flags & (CODEC_FLAG_PASS1 | CODEC_FLAG_PASS2))) {
856
+                char logfilename[1024];
857
+                FILE *f;
858
+                int size;
859
+                char *logbuffer;
860
+                
861
+                snprintf(logfilename, sizeof(logfilename), "%s-%d.log", 
862
+                         pass_logfilename ? 
863
+                         pass_logfilename : DEFAULT_PASS_LOGFILENAME, i);
864
+                if (codec->flags & CODEC_FLAG_PASS1) {
865
+                    f = fopen(logfilename, "w");
866
+                    if (!f) {
867
+                        perror(logfilename);
868
+                        exit(1);
869
+                    }
870
+                    ost->logfile = f;
871
+                } else {
872
+                    /* read the log file */
873
+                    f = fopen(logfilename, "r");
874
+                    if (!f) {
875
+                        perror(logfilename);
876
+                        exit(1);
877
+                    }
878
+                    fseek(f, 0, SEEK_END);
879
+                    size = ftell(f);
880
+                    fseek(f, 0, SEEK_SET);
881
+                    logbuffer = av_malloc(size + 1);
882
+                    if (!logbuffer) {
883
+                        fprintf(stderr, "Could not allocate log buffer\n");
884
+                        exit(1);
885
+                    }
886
+                    fread(logbuffer, 1, size, f);
887
+                    fclose(f);
888
+                    logbuffer[size] = '\0';
889
+                    codec->stats_in = logbuffer;
886 890
                 }
887
-                fread(logbuffer, 1, size, f);
888
-                fclose(f);
889
-                logbuffer[size] = '\0';
890
-                codec->stats_in = logbuffer;
891 891
             }
892 892
         }
893 893
     }
894 894
 
895
+    /* dump the file output parameters - cannot be done before in case
896
+       of stream copy */
897
+    for(i=0;i<nb_output_files;i++) {
898
+        dump_format(output_files[i], i, output_files[i]->filename, 1);
899
+    }
900
+
901
+    /* dump the stream mapping */
902
+    fprintf(stderr, "Stream mapping:\n");
903
+    for(i=0;i<nb_ostreams;i++) {
904
+        ost = ost_table[i];
905
+        fprintf(stderr, "  Stream #%d.%d -> #%d.%d\n",
906
+                ist_table[ost->source_index]->file_index,
907
+                ist_table[ost->source_index]->index,
908
+                ost->file_index, 
909
+                ost->index);
910
+    }
911
+
895 912
     /* open each encoder */
896 913
     for(i=0;i<nb_ostreams;i++) {
897 914
         ost = ost_table[i];
... ...
@@ -1666,17 +1671,21 @@ void opt_audio_codec(const char *arg)
1666 1666
 {
1667 1667
     AVCodec *p;
1668 1668
 
1669
-    p = first_avcodec;
1670
-    while (p) {
1671
-        if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
1672
-            break;
1673
-        p = p->next;
1674
-    }
1675
-    if (p == NULL) {
1676
-        fprintf(stderr, "Unknown audio codec '%s'\n", arg);
1677
-        exit(1);
1669
+    if (!strcmp(arg, "copy")) {
1670
+        audio_stream_copy = 1;
1678 1671
     } else {
1679
-        audio_codec_id = p->id;
1672
+        p = first_avcodec;
1673
+        while (p) {
1674
+            if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_AUDIO)
1675
+                break;
1676
+            p = p->next;
1677
+        }
1678
+        if (p == NULL) {
1679
+            fprintf(stderr, "Unknown audio codec '%s'\n", arg);
1680
+            exit(1);
1681
+        } else {
1682
+            audio_codec_id = p->id;
1683
+        }
1680 1684
     }
1681 1685
 }
1682 1686
 
... ...
@@ -1710,17 +1719,21 @@ void opt_video_codec(const char *arg)
1710 1710
 {
1711 1711
     AVCodec *p;
1712 1712
 
1713
-    p = first_avcodec;
1714
-    while (p) {
1715
-        if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
1716
-            break;
1717
-        p = p->next;
1718
-    }
1719
-    if (p == NULL) {
1720
-        fprintf(stderr, "Unknown video codec '%s'\n", arg);
1721
-        exit(1);
1713
+    if (!strcmp(arg, "copy")) {
1714
+        video_stream_copy = 1;
1722 1715
     } else {
1723
-        video_codec_id = p->id;
1716
+        p = first_avcodec;
1717
+        while (p) {
1718
+            if (!strcmp(p->name, arg) && p->type == CODEC_TYPE_VIDEO)
1719
+                break;
1720
+            p = p->next;
1721
+        }
1722
+        if (p == NULL) {
1723
+            fprintf(stderr, "Unknown video codec '%s'\n", arg);
1724
+            exit(1);
1725
+        } else {
1726
+            video_codec_id = p->id;
1727
+        }
1724 1728
     }
1725 1729
 }
1726 1730
 
... ...
@@ -1921,95 +1934,99 @@ void opt_output_file(const char *filename)
1921 1921
                 fprintf(stderr, "Could not alloc stream\n");
1922 1922
                 exit(1);
1923 1923
             }
1924
-            video_enc = &st->codec;
1925 1924
 
1926
-            codec_id = file_oformat->video_codec;
1927
-            if (video_codec_id != CODEC_ID_NONE)
1928
-                codec_id = video_codec_id;
1929
-
1930
-            video_enc->codec_id = codec_id;
1931
-            video_enc->codec_type = CODEC_TYPE_VIDEO;
1932
-            
1933
-            video_enc->bit_rate = video_bit_rate;
1934
-            video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
1935
-            video_enc->frame_rate = frame_rate; 
1936
-            
1937
-            video_enc->width = frame_width;
1938
-            video_enc->height = frame_height;
1939
-            if (!intra_only)
1940
-                video_enc->gop_size = gop_size;
1941
-            else
1942
-                video_enc->gop_size = 0;
1943
-            if (video_qscale || same_quality) {
1944
-                video_enc->flags |= CODEC_FLAG_QSCALE;
1945
-                video_enc->quality = video_qscale;
1946
-            }
1925
+            video_enc = &st->codec;
1926
+            if (video_stream_copy) {
1927
+                st->stream_copy = 1;
1928
+                video_enc->codec_type = CODEC_TYPE_VIDEO;
1929
+            } else {
1930
+                codec_id = file_oformat->video_codec;
1931
+                if (video_codec_id != CODEC_ID_NONE)
1932
+                    codec_id = video_codec_id;
1933
+                
1934
+                video_enc->codec_id = codec_id;
1935
+                
1936
+                video_enc->bit_rate = video_bit_rate;
1937
+                video_enc->bit_rate_tolerance = video_bit_rate_tolerance;
1938
+                video_enc->frame_rate = frame_rate; 
1939
+                
1940
+                video_enc->width = frame_width;
1941
+                video_enc->height = frame_height;
1942
+
1943
+                if (!intra_only)
1944
+                    video_enc->gop_size = gop_size;
1945
+                else
1946
+                    video_enc->gop_size = 0;
1947
+                if (video_qscale || same_quality) {
1948
+                    video_enc->flags |= CODEC_FLAG_QSCALE;
1949
+                    video_enc->quality = video_qscale;
1950
+                }
1947 1951
             
1948
-            if (use_hq) {
1949
-                video_enc->flags |= CODEC_FLAG_HQ;
1950
-            }
1952
+                if (use_hq) {
1953
+                    video_enc->flags |= CODEC_FLAG_HQ;
1954
+                }
1951 1955
             
1952
-            if (use_4mv) {
1953
-                video_enc->flags |= CODEC_FLAG_HQ;
1954
-                video_enc->flags |= CODEC_FLAG_4MV;
1955
-            }
1956
+                if (use_4mv) {
1957
+                    video_enc->flags |= CODEC_FLAG_HQ;
1958
+                    video_enc->flags |= CODEC_FLAG_4MV;
1959
+                }
1956 1960
             
1957
-            if(use_part)
1958
-                video_enc->flags |= CODEC_FLAG_PART;
1961
+                if(use_part)
1962
+                    video_enc->flags |= CODEC_FLAG_PART;
1959 1963
                
1960 1964
             
1961
-            if (b_frames) {
1962
-                if (codec_id != CODEC_ID_MPEG4) {
1963
-                    fprintf(stderr, "\nB frames encoding only supported by MPEG-4.\n");
1964
-                    exit(1);
1965
+                if (b_frames) {
1966
+                    if (codec_id != CODEC_ID_MPEG4) {
1967
+                        fprintf(stderr, "\nB frames encoding only supported by MPEG-4.\n");
1968
+                        exit(1);
1969
+                    }
1970
+                    video_enc->max_b_frames = b_frames;
1971
+                    video_enc->b_frame_strategy = 0;
1972
+                    video_enc->b_quant_factor = 2.0;
1965 1973
                 }
1966
-                video_enc->max_b_frames = b_frames;
1967
-                video_enc->b_frame_strategy = 0;
1968
-                video_enc->b_quant_factor = 2.0;
1969
-            }
1970 1974
             
1971
-            video_enc->qmin = video_qmin;
1972
-            video_enc->qmax = video_qmax;
1973
-            video_enc->max_qdiff = video_qdiff;
1974
-            video_enc->qblur = video_qblur;
1975
-            video_enc->qcompress = video_qcomp;
1976
-            video_enc->rc_eq = video_rc_eq;
1977
-            video_enc->rc_max_rate = video_rc_max_rate;
1978
-            video_enc->rc_min_rate = video_rc_min_rate;
1979
-            video_enc->rc_buffer_size = video_rc_buffer_size;
1980
-            video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
1981
-            video_enc->i_quant_factor = video_i_qfactor;
1982
-            video_enc->b_quant_factor = video_b_qfactor;
1983
-            video_enc->i_quant_offset = video_i_qoffset;
1984
-            video_enc->b_quant_offset = video_b_qoffset;
1985
-            video_enc->dct_algo = dct_algo;
1986
-            video_enc->idct_algo = idct_algo;
1987
-            if(packet_size){
1988
-                video_enc->rtp_mode= 1;
1989
-                video_enc->rtp_payload_size= packet_size;
1990
-            }
1975
+                video_enc->qmin = video_qmin;
1976
+                video_enc->qmax = video_qmax;
1977
+                video_enc->max_qdiff = video_qdiff;
1978
+                video_enc->qblur = video_qblur;
1979
+                video_enc->qcompress = video_qcomp;
1980
+                video_enc->rc_eq = video_rc_eq;
1981
+                video_enc->rc_max_rate = video_rc_max_rate;
1982
+                video_enc->rc_min_rate = video_rc_min_rate;
1983
+                video_enc->rc_buffer_size = video_rc_buffer_size;
1984
+                video_enc->rc_buffer_aggressivity= video_rc_buffer_aggressivity;
1985
+                video_enc->i_quant_factor = video_i_qfactor;
1986
+                video_enc->b_quant_factor = video_b_qfactor;
1987
+                video_enc->i_quant_offset = video_i_qoffset;
1988
+                video_enc->b_quant_offset = video_b_qoffset;
1989
+                video_enc->dct_algo = dct_algo;
1990
+                video_enc->idct_algo = idct_algo;
1991
+                if(packet_size){
1992
+                    video_enc->rtp_mode= 1;
1993
+                    video_enc->rtp_payload_size= packet_size;
1994
+                }
1991 1995
             
1992
-            if (do_psnr)
1993
-                video_enc->get_psnr = 1;
1994
-            else
1995
-                video_enc->get_psnr = 0;
1996
+                if (do_psnr)
1997
+                    video_enc->get_psnr = 1;
1998
+                else
1999
+                    video_enc->get_psnr = 0;
1996 2000
             
1997
-            video_enc->me_method = me_method;
2001
+                video_enc->me_method = me_method;
1998 2002
 
1999
-            /* two pass mode */
2000
-            if (do_pass) {
2001
-                if (do_pass == 1) {
2002
-                    video_enc->flags |= CODEC_FLAG_PASS1;
2003
-                } else {
2004
-                    video_enc->flags |= CODEC_FLAG_PASS2;
2003
+                /* two pass mode */
2004
+                if (do_pass) {
2005
+                    if (do_pass == 1) {
2006
+                        video_enc->flags |= CODEC_FLAG_PASS1;
2007
+                    } else {
2008
+                        video_enc->flags |= CODEC_FLAG_PASS2;
2009
+                    }
2005 2010
                 }
2006
-            }
2007 2011
             
2008
-            /* XXX: need to find a way to set codec parameters */
2009
-            if (oc->oformat->flags & AVFMT_RGB24) {
2010
-                video_enc->pix_fmt = PIX_FMT_RGB24;
2012
+                /* XXX: need to find a way to set codec parameters */
2013
+                if (oc->oformat->flags & AVFMT_RGB24) {
2014
+                    video_enc->pix_fmt = PIX_FMT_RGB24;
2015
+                }
2011 2016
             }
2012
-
2013 2017
             oc->streams[nb_streams] = st;
2014 2018
             nb_streams++;
2015 2019
         }
... ...
@@ -2022,21 +2039,26 @@ void opt_output_file(const char *filename)
2022 2022
                 fprintf(stderr, "Could not alloc stream\n");
2023 2023
                 exit(1);
2024 2024
             }
2025
+
2025 2026
             audio_enc = &st->codec;
2026
-            codec_id = file_oformat->audio_codec;
2027
-            if (audio_codec_id != CODEC_ID_NONE)
2028
-                codec_id = audio_codec_id;
2029
-            audio_enc->codec_id = codec_id;
2030 2027
             audio_enc->codec_type = CODEC_TYPE_AUDIO;
2031
-            
2032
-            audio_enc->bit_rate = audio_bit_rate;
2033
-            audio_enc->sample_rate = audio_sample_rate;
2034
-            /* For audio codecs other than AC3 we limit */
2035
-            /* the number of coded channels to stereo   */
2036
-            if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
2037
-                audio_enc->channels = 2;
2038
-            } else
2039
-                audio_enc->channels = audio_channels;
2028
+            if (audio_stream_copy) {
2029
+                st->stream_copy = 1;
2030
+            } else {
2031
+                codec_id = file_oformat->audio_codec;
2032
+                if (audio_codec_id != CODEC_ID_NONE)
2033
+                    codec_id = audio_codec_id;
2034
+                audio_enc->codec_id = codec_id;
2035
+                
2036
+                audio_enc->bit_rate = audio_bit_rate;
2037
+                audio_enc->sample_rate = audio_sample_rate;
2038
+                /* For audio codecs other than AC3 we limit */
2039
+                /* the number of coded channels to stereo   */
2040
+                if (audio_channels > 2 && codec_id != CODEC_ID_AC3) {
2041
+                    audio_enc->channels = 2;
2042
+                } else
2043
+                    audio_enc->channels = audio_channels;
2044
+            }
2040 2045
             oc->streams[nb_streams] = st;
2041 2046
             nb_streams++;
2042 2047
         }
... ...
@@ -2058,10 +2080,7 @@ void opt_output_file(const char *filename)
2058 2058
             pstrcpy(oc->comment, sizeof(oc->comment), str_comment);
2059 2059
     }
2060 2060
 
2061
-    output_files[nb_output_files] = oc;
2062
-    /* dump the file content */
2063
-    dump_format(oc, nb_output_files, filename, 1);
2064
-    nb_output_files++;
2061
+    output_files[nb_output_files++] = oc;
2065 2062
 
2066 2063
     strcpy(oc->filename, filename);
2067 2064
 
... ...
@@ -2105,6 +2124,8 @@ void opt_output_file(const char *filename)
2105 2105
     video_disable = 0;
2106 2106
     audio_codec_id = CODEC_ID_NONE;
2107 2107
     video_codec_id = CODEC_ID_NONE;
2108
+    audio_stream_copy = 0;
2109
+    video_stream_copy = 0;
2108 2110
 }
2109 2111
 
2110 2112
 /* prepare dummy protocols for grab */
... ...
@@ -2367,7 +2388,7 @@ const OptionDef options[] = {
2367 2367
     { "minrate", HAS_ARG, {(void*)opt_video_bitrate_min}, "set min video bitrate tolerance (in kbit/s)", "bitrate" },
2368 2368
     { "bufsize", HAS_ARG, {(void*)opt_video_buffer_size}, "set ratecontrol buffere size (in kbit)", "size" },
2369 2369
     { "vd", HAS_ARG | OPT_EXPERT, {(void*)opt_video_device}, "set video grab device", "device" },
2370
-    { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec", "codec" },
2370
+    { "vcodec", HAS_ARG | OPT_EXPERT, {(void*)opt_video_codec}, "force video codec ('copy' to copy stream)", "codec" },
2371 2371
     { "me", HAS_ARG | OPT_EXPERT, {(void*)opt_motion_estimation}, "set motion estimation method", 
2372 2372
       "method" },
2373 2373
     { "dct_algo", HAS_ARG | OPT_EXPERT, {(void*)opt_dct_algo}, "set dct algo",  "algo" },
... ...
@@ -2387,7 +2408,7 @@ const OptionDef options[] = {
2387 2387
     { "ac", HAS_ARG, {(void*)opt_audio_channels}, "set number of audio channels", "channels" },
2388 2388
     { "an", OPT_BOOL, {(void*)&audio_disable}, "disable audio" },
2389 2389
     { "ad", HAS_ARG | OPT_EXPERT, {(void*)opt_audio_device}, "set audio device", "device" },
2390
-    { "acodec", HAS_ARG | OPT_EXPERT, {(void*)opt_audio_codec}, "force audio codec", "codec" },
2390
+    { "acodec", HAS_ARG | OPT_EXPERT, {(void*)opt_audio_codec}, "force audio codec ('copy' to copy stream)", "codec" },
2391 2391
     { "deinterlace", OPT_BOOL | OPT_EXPERT, {(void*)&do_deinterlace}, 
2392 2392
       "deinterlace pictures" },
2393 2393
     { "benchmark", OPT_BOOL | OPT_EXPERT, {(void*)&do_benchmark},