[FFmpeg-trac] #4404(avcodec:new): Cannot decode PNG or TIF files with libavcodec.
FFmpeg
trac at avcodec.org
Mon Mar 30 01:21:09 CEST 2015
#4404: Cannot decode PNG or TIF files with libavcodec.
-------------------------------------+-------------------------------------
Reporter: sgan | Owner:
Type: defect | Status: new
Priority: normal | Component: avcodec
Version: unspecified | Resolution:
Keywords: PNG | Blocked By:
avcodec_decode_video2 | Reproduced by developer: 0
Blocking: |
Analyzed by developer: 0 |
-------------------------------------+-------------------------------------
Comment (by sgan):
So I am still working on it and I think I finally found the solution.
As I am not an libavcodec expert, please fill free to comment.
According to avcodec_open2 documentation,
[http://ffmpeg.org/doxygen/trunk/group__lavc__core.html#ga11f785a188d7d9df71621001465b0f1d]
''Prior to using this function the context has to be allocated with
avcodec_alloc_context3().''
So new code should be something like that (modifications have been
commented as //[sgan]:
{{{
int ff_load_image(uint8_t *data[4], int linesize[4],
int *w, int *h, enum AVPixelFormat *pix_fmt,
const char *filename, void *log_ctx)
{
AVInputFormat *iformat = NULL;
AVFormatContext *format_ctx = NULL;
AVCodec *codec;
AVCodecContext *codec_ctx;
AVFrame *frame;
int frame_decoded, ret = 0;
AVPacket pkt;
av_init_packet(&pkt);
av_register_all();
iformat = av_find_input_format("image2");
if ((ret = avformat_open_input(&format_ctx, filename, iformat, NULL))
< 0) {
av_log(log_ctx, AV_LOG_ERROR,
"Failed to open input file '%s'\n", filename);
return ret;
}
if ((ret = avformat_find_stream_info(format_ctx, NULL)) < 0) {
av_log(log_ctx, AV_LOG_ERROR, "Find stream info failed\n");
return ret;
}
//codec_ctx = format_ctx->streams[0]->codec; //[sgan]To
remove
codec = avcodec_find_decoder(codec_ctx->codec_id); //[sgan]To modify
if (!codec) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to find codec\n");
ret = AVERROR(EINVAL);
goto end;
}
codec_ctx = avcodec_alloc_context3(codec); //[sgan]To add
if (!codec_ctx) return -1; //[sgan]To add
codec_ctx->width=format_ctx->streams[0]->codec->width;
//[sgan]To add
codec_ctx->height=format_ctx->streams[0]->codec->height;
//[sgan]To add
codec_ctx->pix_fmt=format_ctx->streams[0]->codec->pix_fmt; //[sgan]To
add
if ((ret = avcodec_open2(codec_ctx, codec, NULL)) < 0) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to open codec\n");
goto end;
}
if (!(frame = av_frame_alloc()) ) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to alloc frame\n");
ret = AVERROR(ENOMEM);
goto end;
}
ret = av_read_frame(format_ctx, &pkt);
if (ret < 0) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to read frame from file\n");
goto end;
}
ret = avcodec_decode_video2(codec_ctx, frame, &frame_decoded, &pkt);
if (ret < 0 || !frame_decoded) {
av_log(log_ctx, AV_LOG_ERROR, "Failed to decode image from
file\n");
if (ret >= 0)
ret = -1;
goto end;
}
*w = frame->width;
*h = frame->height;
*pix_fmt = frame->format;
if ((ret = av_image_alloc(data, linesize, *w, *h, *pix_fmt, 16)) < 0)
goto end;
ret = 0;
av_image_copy(data, linesize, (const uint8_t **)frame->data,
frame->linesize, *pix_fmt, *w, *h);
end:
av_free_packet(&pkt);
//avcodec_close(codec_ctx); //[sgan]To remove
avcodec_free_context(&codec_ctx); //[sgan]To add
avformat_close_input(&format_ctx);
av_frame_free(&frame);
if (ret < 0)
av_log(log_ctx, AV_LOG_ERROR, "Error loading image file '%s'\n",
filename);
return ret;
}
}}}
It seems that after:
{{{
codec_ctx = avcodec_alloc_context3(codec);
}}}
, some attibutes have to be set (width,height, ...).
Now it is working with PNG and TIFF files also.
--
Ticket URL: <https://trac.ffmpeg.org/ticket/4404#comment:1>
FFmpeg <https://ffmpeg.org>
FFmpeg issue tracker
More information about the FFmpeg-trac
mailing list