[FFmpeg-devel] [PATCH] Codec lookup: do not use codec_id
Nicolas George
nicolas.george
Thu Jul 19 21:47:55 CEST 2007
Hi.
Le septidi 17 messidor, an CCXV, Michael Niedermayer a ?crit?:
> your suggestion is better then the last patch
After some lapse, it is implemented in the attached patch.
I ran the same battery of tests as last time. It works.
> still pleas keep in mind that not every string has a corresponding AVCodec
> and thus the code must not depend on the existance of a AVCodec unless
> one is really actually used for encoding/decoding that is for stream copy
> it has to work with neither encoder nor decoder
> and yes its very well possibe that this doesnt work currently either
>
> but it should be possible to override the input codec and do stream copy
> even if decoder or encoder AVCodec is missing
Do you have an example of how it would be useful? With the current code, as
far as I understand, the input codec is simply ignored.
Anyway, I do not believe that my code makes things worse with that regard,
and it probably makes it easier to change.
Regards,
--
Nicolas George
Index: ffmpeg.c
===================================================================
--- ffmpeg.c (revision 9755)
+++ ffmpeg.c (working copy)
@@ -128,7 +128,7 @@
static char *video_rc_eq="tex^qComp";
static int video_disable = 0;
static int video_discard = 0;
-static int video_codec_id = CODEC_ID_NONE;
+static char *video_codec_name = NULL;
static int video_codec_tag = 0;
static int same_quality = 0;
static int do_deinterlace = 0;
@@ -146,11 +146,11 @@
static float audio_qscale = QSCALE_NONE;
static int audio_disable = 0;
static int audio_channels = 1;
-static int audio_codec_id = CODEC_ID_NONE;
+static char *audio_codec_name = NULL;
static int audio_codec_tag = 0;
static char *audio_language = NULL;
-static int subtitle_codec_id = CODEC_ID_NONE;
+static char *subtitle_codec_name = NULL;
static char *subtitle_language = NULL;
static float mux_preload= 0.5;
@@ -1718,7 +1718,11 @@
ost = ost_table[i];
if (ost->encoding_needed) {
AVCodec *codec;
- codec = avcodec_find_encoder(ost->st->codec->codec_id);
+ codec = ost->st->codec->codec;
+ /* until here, ost->st->codec was used to store future codec
+ * parameters; now, it will be properly used as an
+ * AVCodecContext; it must therefore be reset */
+ ost->st->codec->codec = NULL;
if (!codec) {
fprintf(stderr, "Unsupported codec for output stream #%d.%d\n",
ost->file_index, ost->index);
@@ -1738,7 +1742,13 @@
ist = ist_table[i];
if (ist->decoding_needed) {
AVCodec *codec;
- codec = avcodec_find_decoder(ist->st->codec->codec_id);
+ codec = ist->st->codec->codec;
+ if(codec == NULL)
+ codec = avcodec_find_decoder(ist->st->codec->codec_id);
+ /* until here, ost->st->codec was used to store future codec
+ * parameters; now, it will be properly used as an
+ * AVCodecContext; it must therefore be reset */
+ ist->st->codec->codec = NULL;
if (!codec) {
fprintf(stderr, "Unsupported codec (id=%d) for input stream #%d.%d\n",
ist->st->codec->codec_id, ist->file_index, ist->index);
@@ -2349,32 +2359,24 @@
video_standard = av_strdup(arg);
}
-static void opt_codec(int *pstream_copy, int *pcodec_id,
+static void opt_codec(int *pstream_copy, char **pcodec_name,
int codec_type, const char *arg)
{
- AVCodec *p;
-
- if (!strcmp(arg, "copy")) {
+ if(*pcodec_name != NULL)
+ /*av_free(*pcodec_name)*/;
+ *pstream_copy = 0;
+ if(arg == NULL) {
+ /* nothing */
+ } else if (!strcmp(arg, "copy")) {
*pstream_copy = 1;
} else {
- p = first_avcodec;
- while (p) {
- if (!strcmp(p->name, arg) && p->type == codec_type)
- break;
- p = p->next;
- }
- if (p == NULL) {
- fprintf(stderr, "Unknown codec '%s'\n", arg);
- exit(1);
- } else {
- *pcodec_id = p->id;
- }
+ *pcodec_name = arg == NULL ? NULL : av_strdup(arg);
}
}
static void opt_audio_codec(const char *arg)
{
- opt_codec(&audio_stream_copy, &audio_codec_id, CODEC_TYPE_AUDIO, arg);
+ opt_codec(&audio_stream_copy, &audio_codec_name, CODEC_TYPE_AUDIO, arg);
}
static void opt_audio_tag(const char *arg)
@@ -2418,12 +2420,12 @@
static void opt_video_codec(const char *arg)
{
- opt_codec(&video_stream_copy, &video_codec_id, CODEC_TYPE_VIDEO, arg);
+ opt_codec(&video_stream_copy, &video_codec_name, CODEC_TYPE_VIDEO, arg);
}
static void opt_subtitle_codec(const char *arg)
{
- opt_codec(&subtitle_stream_copy, &subtitle_codec_id, CODEC_TYPE_SUBTITLE, arg);
+ opt_codec(&subtitle_stream_copy, &subtitle_codec_name, CODEC_TYPE_SUBTITLE, arg);
}
static void opt_map(const char *arg)
@@ -2486,12 +2488,31 @@
input_ts_offset = parse_date(arg, 1);
}
+static AVCodec *find_codec_or_die(const char *name, int type, int encoder)
+{
+ AVCodec *codec;
+
+ codec = encoder ?
+ avcodec_find_encoder_by_name(name) :
+ avcodec_find_decoder_by_name(name);
+ if(codec == NULL) {
+ av_log(NULL, AV_LOG_ERROR, "Unknown codec '%s'\n", name);
+ exit(1);
+ }
+ if(codec->type != type) {
+ av_log(NULL, AV_LOG_ERROR, "Invalid codec type '%s'\n", name);
+ exit(1);
+ }
+ return codec;
+}
+
static void opt_input_file(const char *filename)
{
AVFormatContext *ic;
AVFormatParameters params, *ap = ¶ms;
int err, i, ret, rfps, rfps_base;
int64_t timestamp;
+ AVCodec *codec;
if (!strcmp(filename, "-"))
filename = "pipe:";
@@ -2513,8 +2534,18 @@
ap->pix_fmt = frame_pix_fmt;
ap->channel = video_channel;
ap->standard = video_standard;
- ap->video_codec_id = video_codec_id;
- ap->audio_codec_id = audio_codec_id;
+ if(video_codec_name == NULL) {
+ ap->video_codec_id = CODEC_ID_NONE;
+ } else {
+ codec = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 0);
+ ap->video_codec_id = codec->id;
+ }
+ if(audio_codec_name == NULL) {
+ ap->audio_codec_id = CODEC_ID_NONE;
+ } else {
+ codec = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 0);
+ ap->audio_codec_id = codec->id;
+ }
if(pgmyuv_compatibility_hack)
ap->video_codec_id= CODEC_ID_PGMYUV;
@@ -2674,7 +2705,6 @@
{
AVStream *st;
AVCodecContext *video_enc;
- int codec_id;
st = av_new_stream(oc, oc->nb_streams);
if (!st) {
@@ -2711,13 +2741,16 @@
int i;
AVCodec *codec;
- codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
- if (video_codec_id != CODEC_ID_NONE)
- codec_id = video_codec_id;
+ if(video_codec_name == NULL) {
+ int codec_id;
+ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_VIDEO);
+ codec = avcodec_find_encoder(codec_id);
+ } else {
+ codec = find_codec_or_die(video_codec_name, CODEC_TYPE_VIDEO, 1);
+ }
+ video_enc->codec = codec;
+ video_enc->codec_id = codec == NULL ? CODEC_ID_NONE : codec->id;
- video_enc->codec_id = codec_id;
- codec = avcodec_find_encoder(codec_id);
-
for(i=0; i<opt_name_count; i++){
const AVOption *opt;
double d= av_get_double(avctx_opts[CODEC_TYPE_VIDEO], opt_names[i], &opt);
@@ -2821,15 +2854,14 @@
/* reset some key parameters */
video_disable = 0;
- video_codec_id = CODEC_ID_NONE;
- video_stream_copy = 0;
+ opt_video_codec(NULL);
}
static void new_audio_stream(AVFormatContext *oc)
{
AVStream *st;
AVCodecContext *audio_enc;
- int codec_id, i;
+ int i;
st = av_new_stream(oc, oc->nb_streams);
if (!st) {
@@ -2859,7 +2891,15 @@
st->stream_copy = 1;
audio_enc->channels = audio_channels;
} else {
- codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
+ if(audio_codec_name == NULL) {
+ int codec_id;
+ codec_id = av_guess_codec(oc->oformat, NULL, oc->filename, NULL, CODEC_TYPE_AUDIO);
+ audio_enc->codec = avcodec_find_encoder(codec_id);
+ audio_enc->codec_id = codec_id;
+ } else {
+ audio_enc->codec = find_codec_or_die(audio_codec_name, CODEC_TYPE_AUDIO, 1);
+ audio_enc->codec_id = audio_enc->codec->id;
+ }
for(i=0; i<opt_name_count; i++){
const AVOption *opt;
@@ -2868,10 +2908,6 @@
av_set_double(audio_enc, opt_names[i], d);
}
- if (audio_codec_id != CODEC_ID_NONE)
- codec_id = audio_codec_id;
- audio_enc->codec_id = codec_id;
-
if (audio_qscale > QSCALE_NONE) {
audio_enc->flags |= CODEC_FLAG_QSCALE;
audio_enc->global_quality = st->quality = FF_QP2LAMBDA * audio_qscale;
@@ -2889,8 +2925,7 @@
/* reset some key parameters */
audio_disable = 0;
- audio_codec_id = CODEC_ID_NONE;
- audio_stream_copy = 0;
+ opt_audio_codec(NULL);
}
static void opt_new_subtitle_stream(void)
@@ -2924,7 +2959,7 @@
if(d==d && (opt->flags&AV_OPT_FLAG_SUBTITLE_PARAM) && (opt->flags&AV_OPT_FLAG_ENCODING_PARAM))
av_set_double(subtitle_enc, opt_names[i], d);
}
- subtitle_enc->codec_id = subtitle_codec_id;
+ subtitle_enc->codec = find_codec_or_die(subtitle_codec_name, CODEC_TYPE_SUBTITLE, 1);
}
if (subtitle_language) {
@@ -2933,8 +2968,7 @@
subtitle_language = NULL;
}
- subtitle_codec_id = CODEC_ID_NONE;
- subtitle_stream_copy = 0;
+ opt_subtitle_codec(NULL);
}
static void opt_new_audio_stream(void)
@@ -2991,8 +3025,8 @@
exit(1);
}
} else {
- 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_video = file_oformat->video_codec != CODEC_ID_NONE || video_stream_copy || video_codec_name != NULL;
+ use_audio = file_oformat->audio_codec != CODEC_ID_NONE || audio_stream_copy || audio_codec_name != NULL;
/* disable if no corresponding type found and at least one
input file */
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 185 bytes
Desc: Digital signature
URL: <http://lists.mplayerhq.hu/pipermail/ffmpeg-devel/attachments/20070719/3c480a13/attachment.pgp>
More information about the ffmpeg-devel
mailing list