0

I am trying to decode a h264 video stream with ffmpeg and I have a problem when using av_read_frame. No data is put in packet->data.

spy on packet

I want to convert pic in YUV to RGB with sws_scale but when i call it i have an error : bad src image pointers if someone can explain the problem.

thx for reading

here my code :

AVFormatContext* input_ctx  = NULL;
AVStream* video_st          = NULL;
AVCodecContext* decoder_ctx = NULL;
AVCodec* decoder;
AVPacket pkt = { 0 };
AVFrame* pFrameRGB = NULL;
AVFrame* sw_frame = NULL;
DWORD dwWidth   =   704;
DWORD dwHeight  =   576;
struct SwsContext* img_convert_ctx = NULL;

input_ctx = avformat_alloc_context();
ret = avformat_open_input(&input_ctx, "rtsp://****************************/Streaming/Channels/102?profile=Profile_1", NULL, NULL);
if (ret < 0) { 
    fprintf(stderr, "Cannot open input file rtsp://****************************/Streaming/Channels/102?profile=Profile_1");
    goto finish;
}

avformat_find_stream_info(input_ctx, NULL);

int videostream = av_find_best_stream(input_ctx, AVMEDIA_TYPE_VIDEO, -1, -1, &decoder, 0);
if (videostream == AVERROR_STREAM_NOT_FOUND || !decoder)
    printf("Aucun flux video disponible\r\n");
else
    printf("flux video detecte sur streams[%d]\r\n", videostream);
    
av_dump_format(input_ctx, 0, "rtsp://****************************/Streaming/Channels/102?profile=Profile_1", 0);

av_read_play(input_ctx);

AVStream* st = input_ctx->streams[videostream];
video_st = st;

decoder = avcodec_find_decoder(AV_CODEC_ID_H264);
if (!decoder) {
    fprintf(stderr, "Erreur decoder not found");
    goto finish;
}

decoder_ctx = avcodec_alloc_context3(decoder);
if (!decoder_ctx) { 
    ret = AVERROR(ENOMEM);
    goto finish;
}

ret = avcodec_open2(decoder_ctx, NULL, NULL);
if (ret < 0) { 
    fprintf(stderr, "Error opening the decoder: \r\n");
    goto finish;
}

pFrameRGB = av_frame_alloc();
sw_frame = av_frame_alloc();

if (!pFrameRGB || !sw_frame) { 
    ret = AVERROR(ENOMEM);
    goto finish;
}

sw_frame->width = dwWidth;
sw_frame->height = dwHeight;
pFrameRGB->width = dwWidth;
pFrameRGB->height = dwHeight;

numBytes = av_image_get_buffer_size(AV_PIX_FMT_YUV420P, decoder_ctx->width, decoder_ctx->height, 16);
numBytes2 = av_image_get_buffer_size(AV_PIX_FMT_RGB24, decoder_ctx->width, decoder_ctx->height, 16);
        
buffer = (uint8_t *)av_malloc(numBytes * sizeof (uint8_t));
buffer2 = (uint8_t *)av_malloc(numBytes2 * sizeof (uint8_t));

ret = av_image_fill_arrays(sw_frame->data, sw_frame->linesize, buffer, AV_PIX_FMT_YUV420P, decoder_ctx->width, decoder_ctx->height, 1);
if(ret < 0) {
    fprintf(stderr, "Cannot initialize data pointers of AVFrame for buffer YUV!\r\n");
    goto finish; 
}   

ret = av_image_fill_arrays(pFrameRGB->data, pFrameRGB->linesize, buffer2, AV_PIX_FMT_RGB24, decoder_ctx->width, decoder_ctx->height, 1);
if(ret < 0) {
    fprintf(stderr, "Cannot initialize data pointers of AVFrame for buffer RGB!\r\n");
    goto finish; 
}

img_convert_ctx = sws_getContext( decoder_ctx->width, 
                                                    decoder_ctx->height, 
                                                    decoder_ctx->pix_fmt, 
                                                    decoder_ctx->width, 
                                                    decoder_ctx->height, 
                                                    AV_PIX_FMT_RGB24, 
                                                    SWS_BILINEAR, 
                                                    (int)NULL, NULL, NULL);
                                                    
while (ret >= 0) { 
    ret = av_read_frame(input_ctx, &pkt); 
    if (ret < 0)
        break;
    if ((avcodec_send_packet != NULL)&&(avcodec_receive_frame!=NULL)) { 
            ret = avcodec_send_packet(decoder_ctx, pkt);
        if (ret < 0) { 
            fprintf(stderr, "Error during decoding\n");
            goto finish;
        }

        ret = avcodec_receive_frame(decoder_ctx, sw_frame);
        if (ret == AVERROR(EAGAIN) || ret == AVERROR_EOF)
            break;
        else 
            if (ret < 0) { 
                fprintf(stderr, "Error during decoding\n");
                goto finish;
            }

        //avcodec_send_packet replace the height of decoder_ctx by the width
        //here, decoder_ctx->height  = 704
        //i don't understand why
        decoder_ctx->height = dwHeight;

        sws_scale(img_convert_ctx, (const uint8_t * const*)sw_frame->data, sw_frame->linesize, 0, decoder_ctx->height, pFrameRGB->data, pFrameRGB->linesize);

        iNbImages++;
        fprintf(stderr, "%d images saves\r\n", iNbImages);
        lpfnav_packet_unref(&pkt);
    }
}   
New contributor
Hugo Charasss is a new contributor to this site. Take care in asking for clarification, commenting, and answering. Check out our Code of Conduct.

Your Answer

Hugo Charasss is a new contributor. Be nice, and check out our Code of Conduct.

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.