mirror of
https://github.com/FFmpeg/FFmpeg.git
synced 2024-12-23 12:43:46 +02:00
add proper support for subtitles muxing/stream copying
Originally committed as revision 9798 to svn://svn.ffmpeg.org/ffmpeg/trunk
This commit is contained in:
parent
8e0d882b49
commit
11bf3847b3
52
ffmpeg.c
52
ffmpeg.c
@ -150,6 +150,7 @@ static int audio_codec_id = CODEC_ID_NONE;
|
|||||||
static int audio_codec_tag = 0;
|
static int audio_codec_tag = 0;
|
||||||
static char *audio_language = NULL;
|
static char *audio_language = NULL;
|
||||||
|
|
||||||
|
static int subtitle_disable = 0;
|
||||||
static int subtitle_codec_id = CODEC_ID_NONE;
|
static int subtitle_codec_id = CODEC_ID_NONE;
|
||||||
static char *subtitle_language = NULL;
|
static char *subtitle_language = NULL;
|
||||||
|
|
||||||
@ -2624,6 +2625,8 @@ static void opt_input_file(const char *filename)
|
|||||||
case CODEC_TYPE_DATA:
|
case CODEC_TYPE_DATA:
|
||||||
break;
|
break;
|
||||||
case CODEC_TYPE_SUBTITLE:
|
case CODEC_TYPE_SUBTITLE:
|
||||||
|
if(subtitle_disable)
|
||||||
|
ic->streams[i]->discard = AVDISCARD_ALL;
|
||||||
break;
|
break;
|
||||||
case CODEC_TYPE_UNKNOWN:
|
case CODEC_TYPE_UNKNOWN:
|
||||||
break;
|
break;
|
||||||
@ -2647,13 +2650,15 @@ static void opt_input_file(const char *filename)
|
|||||||
rate_emu = 0;
|
rate_emu = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
static void check_audio_video_sub_inputs(int *has_video_ptr, int *has_audio_ptr,
|
||||||
|
int *has_subtitle_ptr)
|
||||||
{
|
{
|
||||||
int has_video, has_audio, i, j;
|
int has_video, has_audio, has_subtitle, i, j;
|
||||||
AVFormatContext *ic;
|
AVFormatContext *ic;
|
||||||
|
|
||||||
has_video = 0;
|
has_video = 0;
|
||||||
has_audio = 0;
|
has_audio = 0;
|
||||||
|
has_subtitle = 0;
|
||||||
for(j=0;j<nb_input_files;j++) {
|
for(j=0;j<nb_input_files;j++) {
|
||||||
ic = input_files[j];
|
ic = input_files[j];
|
||||||
for(i=0;i<ic->nb_streams;i++) {
|
for(i=0;i<ic->nb_streams;i++) {
|
||||||
@ -2665,9 +2670,11 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
|||||||
case CODEC_TYPE_VIDEO:
|
case CODEC_TYPE_VIDEO:
|
||||||
has_video = 1;
|
has_video = 1;
|
||||||
break;
|
break;
|
||||||
|
case CODEC_TYPE_SUBTITLE:
|
||||||
|
has_subtitle = 1;
|
||||||
|
break;
|
||||||
case CODEC_TYPE_DATA:
|
case CODEC_TYPE_DATA:
|
||||||
case CODEC_TYPE_UNKNOWN:
|
case CODEC_TYPE_UNKNOWN:
|
||||||
case CODEC_TYPE_SUBTITLE:
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
abort();
|
abort();
|
||||||
@ -2676,6 +2683,7 @@ static void check_audio_video_inputs(int *has_video_ptr, int *has_audio_ptr)
|
|||||||
}
|
}
|
||||||
*has_video_ptr = has_video;
|
*has_video_ptr = has_video;
|
||||||
*has_audio_ptr = has_audio;
|
*has_audio_ptr = has_audio;
|
||||||
|
*has_subtitle_ptr = has_subtitle;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void new_video_stream(AVFormatContext *oc)
|
static void new_video_stream(AVFormatContext *oc)
|
||||||
@ -2901,19 +2909,12 @@ static void new_audio_stream(AVFormatContext *oc)
|
|||||||
audio_stream_copy = 0;
|
audio_stream_copy = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void opt_new_subtitle_stream(void)
|
static void new_subtitle_stream(AVFormatContext *oc)
|
||||||
{
|
{
|
||||||
AVFormatContext *oc;
|
|
||||||
AVStream *st;
|
AVStream *st;
|
||||||
AVCodecContext *subtitle_enc;
|
AVCodecContext *subtitle_enc;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
if (nb_output_files <= 0) {
|
|
||||||
fprintf(stderr, "At least one output file must be specified\n");
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
oc = output_files[nb_output_files - 1];
|
|
||||||
|
|
||||||
st = av_new_stream(oc, oc->nb_streams);
|
st = av_new_stream(oc, oc->nb_streams);
|
||||||
if (!st) {
|
if (!st) {
|
||||||
fprintf(stderr, "Could not alloc stream\n");
|
fprintf(stderr, "Could not alloc stream\n");
|
||||||
@ -2941,6 +2942,7 @@ static void opt_new_subtitle_stream(void)
|
|||||||
subtitle_language = NULL;
|
subtitle_language = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
subtitle_disable = 0;
|
||||||
subtitle_codec_id = CODEC_ID_NONE;
|
subtitle_codec_id = CODEC_ID_NONE;
|
||||||
subtitle_stream_copy = 0;
|
subtitle_stream_copy = 0;
|
||||||
}
|
}
|
||||||
@ -2967,10 +2969,22 @@ static void opt_new_video_stream(void)
|
|||||||
new_video_stream(oc);
|
new_video_stream(oc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void opt_new_subtitle_stream(void)
|
||||||
|
{
|
||||||
|
AVFormatContext *oc;
|
||||||
|
if (nb_output_files <= 0) {
|
||||||
|
fprintf(stderr, "At least one output file must be specified\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
oc = output_files[nb_output_files - 1];
|
||||||
|
new_subtitle_stream(oc);
|
||||||
|
}
|
||||||
|
|
||||||
static void opt_output_file(const char *filename)
|
static void opt_output_file(const char *filename)
|
||||||
{
|
{
|
||||||
AVFormatContext *oc;
|
AVFormatContext *oc;
|
||||||
int use_video, use_audio, input_has_video, input_has_audio, i;
|
int use_video, use_audio, use_subtitle;
|
||||||
|
int input_has_video, input_has_audio, input_has_subtitle, i;
|
||||||
AVFormatParameters params, *ap = ¶ms;
|
AVFormatParameters params, *ap = ¶ms;
|
||||||
|
|
||||||
if (!strcmp(filename, "-"))
|
if (!strcmp(filename, "-"))
|
||||||
@ -3001,15 +3015,19 @@ static void opt_output_file(const char *filename)
|
|||||||
} else {
|
} else {
|
||||||
use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_id != CODEC_ID_NONE;
|
use_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_id != CODEC_ID_NONE;
|
||||||
use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_id != CODEC_ID_NONE;
|
use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_id != CODEC_ID_NONE;
|
||||||
|
use_subtitle = file_oformat->subtitle_codec != CODEC_ID_NONE || subtitle_stream_copy || subtitle_codec_id != CODEC_ID_NONE;
|
||||||
|
|
||||||
/* disable if no corresponding type found and at least one
|
/* disable if no corresponding type found and at least one
|
||||||
input file */
|
input file */
|
||||||
if (nb_input_files > 0) {
|
if (nb_input_files > 0) {
|
||||||
check_audio_video_inputs(&input_has_video, &input_has_audio);
|
check_audio_video_sub_inputs(&input_has_video, &input_has_audio,
|
||||||
|
&input_has_subtitle);
|
||||||
if (!input_has_video)
|
if (!input_has_video)
|
||||||
use_video = 0;
|
use_video = 0;
|
||||||
if (!input_has_audio)
|
if (!input_has_audio)
|
||||||
use_audio = 0;
|
use_audio = 0;
|
||||||
|
if (!input_has_subtitle)
|
||||||
|
use_subtitle = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* manual disable */
|
/* manual disable */
|
||||||
@ -3019,6 +3037,9 @@ static void opt_output_file(const char *filename)
|
|||||||
if (video_disable) {
|
if (video_disable) {
|
||||||
use_video = 0;
|
use_video = 0;
|
||||||
}
|
}
|
||||||
|
if (subtitle_disable) {
|
||||||
|
use_subtitle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
if (use_video) {
|
if (use_video) {
|
||||||
new_video_stream(oc);
|
new_video_stream(oc);
|
||||||
@ -3028,6 +3049,10 @@ static void opt_output_file(const char *filename)
|
|||||||
new_audio_stream(oc);
|
new_audio_stream(oc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (use_subtitle) {
|
||||||
|
new_subtitle_stream(oc);
|
||||||
|
}
|
||||||
|
|
||||||
oc->timestamp = rec_timestamp;
|
oc->timestamp = rec_timestamp;
|
||||||
|
|
||||||
if (str_title)
|
if (str_title)
|
||||||
@ -3635,6 +3660,7 @@ const OptionDef options[] = {
|
|||||||
{ "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
|
{ "alang", HAS_ARG | OPT_STRING | OPT_AUDIO, {(void *)&audio_language}, "set the ISO 639 language code (3 letters) of the current audio stream" , "code" },
|
||||||
|
|
||||||
/* subtitle options */
|
/* subtitle options */
|
||||||
|
{ "sn", OPT_BOOL | OPT_SUBTITLE, {(void*)&subtitle_disable}, "disable subtitle" },
|
||||||
{ "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
|
{ "scodec", HAS_ARG | OPT_SUBTITLE, {(void*)opt_subtitle_codec}, "force subtitle codec ('copy' to copy stream)", "codec" },
|
||||||
{ "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
|
{ "newsubtitle", OPT_SUBTITLE, {(void*)opt_new_subtitle_stream}, "add a new subtitle stream to the current output stream" },
|
||||||
{ "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
|
{ "slang", HAS_ARG | OPT_STRING | OPT_SUBTITLE, {(void *)&subtitle_language}, "set the ISO 639 language code (3 letters) of the current subtitle stream" , "code" },
|
||||||
|
@ -186,6 +186,8 @@ typedef struct AVOutputFormat {
|
|||||||
*/
|
*/
|
||||||
const struct AVCodecTag **codec_tag;
|
const struct AVCodecTag **codec_tag;
|
||||||
|
|
||||||
|
enum CodecID subtitle_codec; /**< default subtitle codec */
|
||||||
|
|
||||||
/* private fields */
|
/* private fields */
|
||||||
struct AVOutputFormat *next;
|
struct AVOutputFormat *next;
|
||||||
} AVOutputFormat;
|
} AVOutputFormat;
|
||||||
|
Loading…
Reference in New Issue
Block a user