Question

Je décoder de la vidéo sur libavcodec, en utilisant le code suivant:

//Open input file
if(avformat_open_input(&ctx, filename, NULL, NULL)!=0)
    return FALSE; // Couldn't open file
if(avformat_find_stream_info(ctx, NULL)<0)
    return FALSE; // Couldn't find stream information
videoStream = -1;
//find video stream
for(i=0; i<ctx->nb_streams; i++)
{       
    if((ctx->streams[i])->codec->codec_type==AVMEDIA_TYPE_VIDEO)
    {
        videoStream=i;
        break;
    }
}
if (videoStream == -1)
    return FALSE; // Didn't find a video stream
video_codec_ctx=ctx->streams[videoStream]->codec;
//find decoder
video_codec=avcodec_find_decoder(video_codec_ctx->codec_id);
if(video_codec==NULL)
    return FALSE; // Codec not found
if(avcodec_open(video_codec_ctx, video_codec)<0)
    return -1; // Could not open codec
video_frame=avcodec_alloc_frame();
scaled_frame=avcodec_alloc_frame();
static struct SwsContext *img_convert_ctx; 
if(img_convert_ctx == NULL) 
{
      int w = video_codec_ctx->width;
      int h = video_codec_ctx->height;
      img_convert_ctx = sws_getContext(w, h, 
                        video_codec_ctx->pix_fmt, 
                        w, h, dst_pix_fmt, SWS_BICUBIC, 
                        NULL, NULL, NULL);
      if(img_convert_ctx == NULL) {
        fprintf(stderr, "Cannot initialize the conversion context!\n");
        return FALSE;
      }
}
while(b_play) 
{
    if (av_read_frame(ctx, &packet) < 0)
    {
        break;
    }
    if(packet.stream_index==videoStream) {
    // Decode video frame   
        avcodec_decode_video2(video_codec_ctx, video_frame, &frameFinished,
                         &packet);
        // Did we get a video frame?
        if(frameFinished) 
        {
            if (video_codec_ctx->pix_fmt != dst_pix_fmt)
            {                       
                if (video_codec_ctx->pix_fmt != dst_pix_fmt)            
                     sws_scale(img_convert_ctx, video_frame->data, 
                              video_frame->linesize, 0, 
                              video_codec_ctx->height, 
                              scaled_frame->data, scaled_frame->linesize);              
            }           
        }
}
av_free_packet(&packet);
}

Le code fonctionne correctement, mais il est nécessaire de convertir chaque image au format requis.Est-il possible de définir le format de pixel pour le décodage pour obtenir le format correct sans sws_scale?

Merci beaucoup pour vos réponses.

Était-ce utile?

La solution

ffmpeg's AVCodec les instances (statique décodeur "usine" objets) chaque définir un tableau de pixels formats pris en charge, dénoncé par la valeur -1.

L' AVCodecContext (décodeur exemple), les objets ont une fonction de callback appelé pointeur get_format:il est un pointeur de fonction dans cette structure.

Cette fonction de rappel est appelée, à un certain moment de l'initialisation du codec, avec l' AVCodec l'objet de fabrique de la gamme de formats pris en charge, et le rappel est censé choisir l'un des formats du tableau (un peu comme "choisissez une carte, n'importe quelle carte") et de renvoyer cette valeur.L'implémentation par défaut de cette get_format callback est une fonction appelée avcodec_default_get_format.(C'est installé avcodec_get_context_defaults2).Cette valeur par défaut de la fonction met en œuvre la "choisissez un format de" logique tout simplement:il choisit le premier élément du tableau qui n'est pas un matériel accel-seulement le format de pixel.

Si vous souhaitez que le codec pour fonctionner avec un autre format de pixel, ce que vous pouvez faire est d'installer votre propre get_format rappel dans le contexte de l'objet.Cependant, la fonction de rappel doit retourner une valeur dans le tableau (comme le choix du menu).Il ne peut pas retourner une valeur arbitraire.Le codec prendra en charge uniquement les formats qu'il indique dans le tableau.

Parcourir le tableau des formats disponibles et choisir le meilleur.Si vous avez de la chance, c'est exactement celui que vous voulez vraiment et les sws_scale la fonction n'aurez pas à faire de pixel de conversion de format.(De plus, si vous ne demandez pas à l'échelle ou de la culture de l'image, sws_scale faut reconnaître que la conversion est un noop.)

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top