[Libav-user] How to access the struct AVCodecTag?

classic Classic list List threaded Threaded
12 messages Options
Reply | Threaded
Open this post in threaded view
|

[Libav-user] How to access the struct AVCodecTag?

Giuseppe Torelli
Hello,

I want to fill two combo boxes in a GTK+3 program with the container and its relevant codecs. I have this code:

#include <stdlib.h>
#include <string.h>
#include <libavcodec/avcodec.h>
#include <libavutil/opt.h>
#include <libavformat/avformat.h>

int main(int argc, char **argv)
{
avcodec_register_all();
av_register_all();

AVCodec *encoder = NULL;
struct AVCodecTag **avctag;
AVOutputFormat *outputFormat = NULL;

const char *file = "file.mp4";
outputFormat = av_guess_format(0, file, 0);

if( ! outputFormat)
{
printf ("No container found\n");
exit (1);
}
printf("%s %d\n",outputFormat->long_name,outputFormat->video_codec);

avctag = outputFormat->codec_tag;
printf("%d\n", (outputFormat->codec_tag[0])->id);
}

gcc gives this output:
enum_codec.c:60:9: warning: assignment from incompatible pointer type [-Wincompatible-pointer-types]
  avctag = outputFormat->codec_tag;
         ^
enum_codec.c:61:45: error: dereferencing pointer to incomplete type ‘const struct AVCodecTag’
  printf("%d\n", (outputFormat->codec_tag[0])->id);

Even adding this in the code it doesn't make any change:

struct AVCodecTag
{
enum AVCodecID id;
unsigned int tag;
};

Can someone explain how to access id and tag inside AVCodecTag?

Many thanks
GiuTor
--
Instagram: the.italian.dude

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Carl Eugen Hoyos-2
Am Di., 17. März 2020 um 20:42 Uhr schrieb Giuseppe Torelli
<[hidden email]>:

> I want to fill two combo boxes in a GTK+3 program with the container and its relevant codecs.

You cannot use AVCodecTag to achieve this, library users are not
supposed to access it.

FFmpeg does not export information about supported codecs in containers, this
information is not even always available within libavformat, users are allowed
to abuse the library.

I believe you - as gui author - are responsible to offer compatible
combinations to
your users.

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Giuseppe Torelli
Hi Carl,

many thanks for replying. I'm really surprised there is no way to get all the encoders linked to a particular container. I was able to use avcodec_find_encoder(28) where 28 is the ID for MPEG-4 Part 14 and I correctly get "libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" but of course there is also libx265 that encodes a video in the MP4 format. I thought it was possible to get sich a list.

Many thanks for replying.
Giuseppe
--
Instagram: the.italian.dude


On Tue, 17 Mar 2020 at 20:45, Carl Eugen Hoyos <[hidden email]> wrote:
Am Di., 17. März 2020 um 20:42 Uhr schrieb Giuseppe Torelli
<[hidden email]>:

> I want to fill two combo boxes in a GTK+3 program with the container and its relevant codecs.

You cannot use AVCodecTag to achieve this, library users are not
supposed to access it.

FFmpeg does not export information about supported codecs in containers, this
information is not even always available within libavformat, users are allowed
to abuse the library.

I believe you - as gui author - are responsible to offer compatible
combinations to
your users.

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Carl Eugen Hoyos-2
Am Di., 17. März 2020 um 21:50 Uhr schrieb Giuseppe Torelli
<[hidden email]>:

> many thanks for replying. I'm really surprised there is no way to get all the encoders
> linked to a particular container.

You can get a default encoder for a given container but as explained
FFmpeg expects its
users to know what to put in a specific container (libavformat may
fail but if it does not
fail, this is still not an indication that the output file will be
readable at all or by specific
software).

> I was able to use avcodec_find_encoder(28) where 28 is the ID for MPEG-4 Part 14 and I
> correctly get "libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" but of course there
> is also libx265 that encodes a video in the MP4 format.

I may misunderstand but avcodec_find_encoder() takes a codec_id, it
has no connection
at all to containers.
(H264 is 27 here, are you testing an ancient FFmpeg version?)

Please find out what top-posting means and avoid it here, Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Anton Shekhovtsov
In reply to this post by Giuseppe Torelli


вт, 17 мар. 2020 г. в 22:50, Giuseppe Torelli <[hidden email]>:
Hi Carl,

many thanks for replying. I'm really surprised there is no way to get all the encoders linked to a particular container. I was able to use avcodec_find_encoder(28) where 28 is the ID for MPEG-4 Part 14 and I correctly get "libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" but of course there is also libx265 that encodes a video in the MP4 format. I thought it was possible to get sich a list.

Many thanks for replying.
Giuseppe
--
Instagram: the.italian.dude


On Tue, 17 Mar 2020 at 20:45, Carl Eugen Hoyos <[hidden email]> wrote:
Am Di., 17. März 2020 um 20:42 Uhr schrieb Giuseppe Torelli
<[hidden email]>:

> I want to fill two combo boxes in a GTK+3 program with the container and its relevant codecs.

You cannot use AVCodecTag to achieve this, library users are not
supposed to access it.

FFmpeg does not export information about supported codecs in containers, this
information is not even always available within libavformat, users are allowed
to abuse the library.

I believe you - as gui author - are responsible to offer compatible
combinations to
your users.

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

I'm not sure if this is completely sane but I'm using this method for testing how FFMpeg can mix codec and container: create memory writing context, prepare writing of container, add single stream with the specific encoding format, try to finish. 
If there is any error assume the format is not supported in the container.
 

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Giuseppe Torelli
In reply to this post by Giuseppe Torelli
Hello again,

Olive Video Editor allows the user to choose the codec according to the selected container. I went into the sources and I couldn't find the codec names hardcoded into it. So there must be a way as this editor uses libav*. Unfortunately I couldn't understand how it does...
--
Instagram: the.italian.dude


On Tue, 17 Mar 2020 at 20:50, Giuseppe Torelli <[hidden email]> wrote:
Hi Carl,

many thanks for replying. I'm really surprised there is no way to get all the encoders linked to a particular container. I was able to use avcodec_find_encoder(28) where 28 is the ID for MPEG-4 Part 14 and I correctly get "libx264 H.264 / AVC / MPEG-4 AVC / MPEG-4 part 10" but of course there is also libx265 that encodes a video in the MP4 format. I thought it was possible to get sich a list.

Many thanks for replying.
Giuseppe
--
Instagram: the.italian.dude


On Tue, 17 Mar 2020 at 20:45, Carl Eugen Hoyos <[hidden email]> wrote:
Am Di., 17. März 2020 um 20:42 Uhr schrieb Giuseppe Torelli
<[hidden email]>:

> I want to fill two combo boxes in a GTK+3 program with the container and its relevant codecs.

You cannot use AVCodecTag to achieve this, library users are not
supposed to access it.

FFmpeg does not export information about supported codecs in containers, this
information is not even always available within libavformat, users are allowed
to abuse the library.

I believe you - as gui author - are responsible to offer compatible
combinations to
your users.

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Giuseppe Torelli
In reply to this post by Carl Eugen Hoyos-2
I may misunderstand but avcodec_find_encoder() takes a codec_id, it
has no connection
at all to containers.
(H264 is 27 here, are you testing an ancient FFmpeg version?)

I have ffmpeg 3.4.6 by the way 28 is the id for MPEG-4 Part 14 not libx264.
 
Please find out what top-posting means and avoid it here, Carl Eugen

Ok.
 

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Carl Eugen Hoyos-2
Am Di., 17. März 2020 um 22:38 Uhr schrieb Giuseppe Torelli
<[hidden email]>:
>
>> I may misunderstand but avcodec_find_encoder() takes a codec_id, it
>> has no connection at all to containers.
>> (H264 is 27 here, are you testing an ancient FFmpeg version?)
>>
> I have ffmpeg 3.4.6 by the way 28 is the id for MPEG-4 Part 14 not libx264.

The constant AV_CODEC_ID_H264 is 28 in old versions of FFmpeg, 27 in
newer versions. The value has nothing to do with MPEG-4 Part 14
(it is used for the codec described in MPEG-4 part 10).

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Giuseppe Torelli
In reply to this post by Anton Shekhovtsov

I'm not sure if this is completely sane but I'm using this method for testing how FFMpeg can mix codec and container: create memory writing context, prepare writing of container, add single stream with the specific encoding format, try to finish. 
If there is any error assume the format is not supported in the container.

Would you please share some code?

Thanks

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Anton Shekhovtsov


вт, 17 мар. 2020 г. в 23:51, Giuseppe Torelli <[hidden email]>:

I'm not sure if this is completely sane but I'm using this method for testing how FFMpeg can mix codec and container: create memory writing context, prepare writing of container, add single stream with the specific encoding format, try to finish. 
If there is any error assume the format is not supported in the container.

Would you please share some code?
 
This is part of VirtualDub2

    IOWBuffer io;
    int buf_size = 4096;
    void* buf = av_malloc(buf_size);
    AVIOContext* avio_ctx = avio_alloc_context((unsigned char*)buf,buf_size,1,&io,0,&IOWBuffer::Write,&IOWBuffer::Seek);
    AVFormatContext* ofmt = avformat_alloc_context();
    ofmt->pb = avio_ctx;
    ofmt->oformat = this->ofmt->oformat;
    AVStream* st = avformat_new_stream(ofmt, 0);
    avcodec_parameters_copy(st->codecpar, si.st->codecpar);
    st->sample_aspect_ratio = si.st->sample_aspect_ratio;
    st->avg_frame_rate = si.st->avg_frame_rate;
    av_stream_set_r_frame_rate(st,st->avg_frame_rate);
    st->time_base = si.st->time_base;

    if(st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO){
      if(ofmt->oformat==av_guess_format("mp4", 0, 0)){
        st->codecpar->codec_tag = 0;
      }
    }

    bool failed = true;
    if(avformat_write_header(ofmt, 0)<0) goto cleanup;
    if(av_write_trailer(ofmt)<0) goto cleanup;
    failed = false;

  cleanup:
    av_free(avio_ctx->buffer);
    av_free(avio_ctx);
    avformat_free_context(ofmt);
    if(failed){
      std::string msg;
      msg += avcodec_get_name(codec_id);
      msg += ": codec not currently supported in container ";
      msg += format_name;
      mContext.mpCallbacks->SetError(msg.c_str());
      return false;
    }
   

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Giuseppe Torelli
Many thanks mate.

_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".
Reply | Threaded
Open this post in threaded view
|

Re: How to access the struct AVCodecTag?

Carl Eugen Hoyos-2
In reply to this post by Anton Shekhovtsov
Am Di., 17. März 2020 um 23:16 Uhr schrieb Anton Shekhovtsov
<[hidden email]>:

>
>
>
> вт, 17 мар. 2020 г. в 23:51, Giuseppe Torelli <[hidden email]>:
>>>
>>>
>>> I'm not sure if this is completely sane but I'm using this method for testing how FFMpeg can mix codec and container: create memory writing context, prepare writing of container, add single stream with the specific encoding format, try to finish.
>>> If there is any error assume the format is not supported in the container.
>>
>>
>> Would you please share some code?
>
>
> https://sourceforge.net/p/vdfiltermod/cch_input/ci/master/tree/export.cpp#l884
> This is part of VirtualDub2
>
>     IOWBuffer io;
>     int buf_size = 4096;
>     void* buf = av_malloc(buf_size);
>     AVIOContext* avio_ctx = avio_alloc_context((unsigned char*)buf,buf_size,1,&io,0,&IOWBuffer::Write,&IOWBuffer::Seek);
>     AVFormatContext* ofmt = avformat_alloc_context();
>     ofmt->pb = avio_ctx;
>     ofmt->oformat = this->ofmt->oformat;
>     AVStream* st = avformat_new_stream(ofmt, 0);
>     avcodec_parameters_copy(st->codecpar, si.st->codecpar);
>     st->sample_aspect_ratio = si.st->sample_aspect_ratio;
>     st->avg_frame_rate = si.st->avg_frame_rate;
>     av_stream_set_r_frame_rate(st,st->avg_frame_rate);
>     st->time_base = si.st->time_base;
>
>     if(st->codecpar->codec_type==AVMEDIA_TYPE_AUDIO){
>       if(ofmt->oformat==av_guess_format("mp4", 0, 0)){
>         st->codecpar->codec_tag = 0;
>       }
>     }
>
>     bool failed = true;
>     if(avformat_write_header(ofmt, 0)<0) goto cleanup;
>     if(av_write_trailer(ofmt)<0) goto cleanup;

As explained, this will not fail for some invalid combinations.

Carl Eugen
_______________________________________________
Libav-user mailing list
[hidden email]
https://ffmpeg.org/mailman/listinfo/libav-user

To unsubscribe, visit link above, or email
[hidden email] with subject "unsubscribe".