Apply libav 12.1 53/142653/2 accepted/tizen/4.0/unified/20170829.015816 accepted/tizen/unified/20170822.113057 submit/tizen/20170822.010353 submit/tizen_4.0/20170828.100004 submit/tizen_4.0/20170828.110004
authorHaejeong Kim <backto.kim@samsung.com>
Mon, 7 Aug 2017 02:54:02 +0000 (11:54 +0900)
committerHaejeong Kim <backto.kim@samsung.com>
Mon, 7 Aug 2017 06:12:53 +0000 (15:12 +0900)
Change-Id: Ic93a7190a1be1d8deefd7e70cd0ba4984af34b82

formats/ffmpeg/mm_file_format_ffmpeg.c
formats/ffmpeg/mm_file_format_frame.c
packaging/libmm-fileinfo.spec

index ca287c9..2a44750 100755 (executable)
@@ -24,6 +24,7 @@
 
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
+#include <libavutil/imgutils.h>
 #include <libswscale/swscale.h>
 #include <mm_error.h>
 #include <mm_types.h>
@@ -315,8 +316,8 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext)
        formatContext->audioTotalTrackNum = 0;
 
        for (i = 0; i < pFormatCtx->nb_streams; i++) {
-               if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
-                       debug_msg(RELEASE, "FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
+               if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
+                       debug_msg(RELEASE, "FFMPEG video codec id: 0x%08X\n", pFormatCtx->streams[i]->codecpar->codec_id);
 
                        AVPacket pkt = pFormatCtx->streams[i]->attached_pic;
                        if ((pkt.data != NULL) && (pkt.size > 0))
@@ -325,8 +326,8 @@ int mmfile_format_open_ffmpg(MMFileFormatContext *formatContext)
                        /*eventhough codec_id is 0, avformat_find_stream_info() can find proper codec_id. */
                        formatContext->videoTotalTrackNum += 1;
                }
-               if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
-                       debug_msg(RELEASE, "FFMPEG audio codec id: 0x%08X\n", pFormatCtx->streams[i]->codec->codec_id);
+               if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
+                       debug_msg(RELEASE, "FFMPEG audio codec id: 0x%08X\n", pFormatCtx->streams[i]->codecpar->codec_id);
                        formatContext->audioTotalTrackNum += 1;
                }
        }
@@ -377,8 +378,8 @@ EXPORT_API
 int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
 {
        AVFormatContext     *pFormatCtx = NULL;
-       AVCodecContext      *pAudioCodecCtx = NULL;
-       AVCodecContext      *pVideoCodecCtx = NULL;
+       AVCodecParameters      *pAudioCodecCtx = NULL;
+       AVCodecParameters      *pVideoCodecCtx = NULL;
 
        MMFileFormatStream  *videoStream = NULL;
        MMFileFormatStream  *audioStream = NULL;
@@ -426,7 +427,7 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
 
        unsigned int i = 0;
        for (i = 0; i < pFormatCtx->nb_streams; i++) {
-               if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+               if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                        if (formatContext->videoStreamId == -1) {
                                videoStream = mmfile_malloc(sizeof(MMFileFormatStream));
                                if (NULL == videoStream) {
@@ -440,7 +441,7 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
                                formatContext->videoStreamId = i;
                                formatContext->videoTotalTrackNum += 1;
 
-                               pVideoCodecCtx = pFormatCtx->streams[i]->codec;
+                               pVideoCodecCtx = pFormatCtx->streams[i]->codecpar;
                                if (pVideoCodecCtx) {
                                        videoStream->codecId            = ConvertVideoCodecEnum(pVideoCodecCtx->codec_id);
                                        if (videoStream->codecId == MM_VIDEO_CODEC_NONE) {
@@ -476,7 +477,7 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
                                }
                        }
                }
-               else if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_AUDIO) {
+               else if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
                        if (formatContext->audioStreamId == -1) {
                                audioStream = mmfile_malloc(sizeof(MMFileFormatStream));
                                if (NULL == audioStream) {
@@ -490,17 +491,19 @@ int mmfile_format_read_stream_ffmpg(MMFileFormatContext *formatContext)
                                formatContext->audioStreamId = i;
                                formatContext->audioTotalTrackNum += 1;
 
-                               pAudioCodecCtx = pFormatCtx->streams[i]->codec;
+                               pAudioCodecCtx = pFormatCtx->streams[i]->codecpar;
                                if (pAudioCodecCtx) {
                                        audioStream->codecId            = ConvertAudioCodecEnum(pAudioCodecCtx->codec_id);
                                        audioStream->bitRate            = pAudioCodecCtx->bit_rate;
                                        audioStream->nbChannel          = pAudioCodecCtx->channels;
                                        audioStream->samplePerSec       = pAudioCodecCtx->sample_rate;
+#if 0
                                        if (audioStream->codecId == MM_AUDIO_CODEC_FLAC)
                                                audioStream->bitPerSample = pAudioCodecCtx->bits_per_raw_sample;
                                        else
+#endif
                                                audioStream->bitPerSample = pAudioCodecCtx->bits_per_coded_sample;
-                                       audioStream->is_uhqa = __check_uhqa(audioStream->samplePerSec, pFormatCtx->streams[i]->codec->sample_fmt);
+                                       audioStream->is_uhqa = __check_uhqa(audioStream->samplePerSec, pFormatCtx->streams[i]->codecpar->format);
                                }
                        }
                }
@@ -583,7 +586,7 @@ int mmfile_format_read_tag_ffmpg(MMFileFormatContext *formatContext)
                        /*refer to mov_read_covr() in ffmpeg.*/
                        if (st != NULL) {
                                AVPacket pkt = st->attached_pic;
-                               int codec_id = st->codec->codec_id;
+                               int codec_id = st->codecpar->codec_id;
 
                                if ((pkt.data != NULL) && (pkt.size > 0)) {
                                        /*Set mime type*/
@@ -723,11 +726,11 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
        AVFormatContext *pFormatCtx = NULL;
        AVCodecContext  *pVideoCodecCtx = NULL;
        AVCodec                 *pVideoCodec = NULL;
+       AVCodecParameters *pVideoCodecPar = NULL;
        AVFrame                 *pFrame = NULL;
-       AVFrame                 *pFrameRGB = NULL;
 
-       int width;
-       int height;
+       int width = 0;
+       int height = 0;
        int numBytes = 0;
        int ret = 0;
 
@@ -743,18 +746,31 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
        pFormatCtx = formatContext->privateFormatData;
 
        if (formatContext->videoStreamId != -1) {
-               pVideoCodecCtx = pFormatCtx->streams[formatContext->videoStreamId]->codec;
-               if (NULL == pVideoCodecCtx) {
+               pVideoCodecPar = pFormatCtx->streams[formatContext->videoStreamId]->codecpar;
+               if (NULL == pVideoCodecPar) {
                        debug_error(DEBUG, "invalid param\n");
                        return MMFILE_FORMAT_FAIL;
                }
 
-               pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);
+               pVideoCodec = avcodec_find_decoder(pVideoCodecPar->codec_id);
                if (NULL == pVideoCodec) {
                        debug_error(DEBUG, "error: avcodec_find_decoder failed\n");
                        return MMFILE_FORMAT_FAIL;
                }
 
+               pVideoCodecCtx = avcodec_alloc_context3(pVideoCodec);
+               if (NULL == pVideoCodecCtx) {
+                       debug_error(DEBUG, "error: avcodec_alloc_context3 failed\n");
+                       return MMFILE_FORMAT_FAIL;
+               }
+
+               ret = avcodec_parameters_to_context(pVideoCodecCtx, pVideoCodecPar);
+               if (ret < 0) {
+                       debug_error(DEBUG, "error: avcodec_parameters_to_context\n");
+                       avcodec_free_context(&pVideoCodecCtx);
+                       return MMFILE_FORMAT_FAIL;
+               }
+
                debug_msg(RELEASE, "flag: 0x%08X\n", pVideoCodec->capabilities);
                /* debug_msg(RELEASE, "  DRAW_HORIZ_BAND : %d\n", pVideoCodec->capabilities & CODEC_CAP_DRAW_HORIZ_BAND ? 1 : 0); */
                /* debug_msg(RELEASE, "  DR1             : %d\n", pVideoCodec->capabilities & CODEC_CAP_DR1 ? 1 : 0); */
@@ -783,14 +799,6 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
                        return MMFILE_FORMAT_FAIL;
                }
 
-               pFrameRGB = av_frame_alloc();
-
-               if (!pFrameRGB) {
-                       debug_error(DEBUG, "error: pFrame or pFrameRGB is NULL\n");
-                       ret = MMFILE_FORMAT_FAIL;
-                       goto exception;
-               }
-
                /* search & decode */
                /* seek_ts = formatContext->duration > _SHORT_MEDIA_LIMIT ? seek_ts : 0; */     /*if short media, seek first key frame*/
                ret = _get_first_good_video_frame(pFormatCtx, pVideoCodecCtx, formatContext->videoStreamId, &pFrame, formatContext->cdis);
@@ -816,21 +824,24 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
                        height = pVideoCodecCtx->height;
                }
 
-               numBytes = avpicture_get_size(AV_PIX_FMT_RGB24, width, height);
+               numBytes = av_image_get_buffer_size(AV_PIX_FMT_RGB24, width, height, 1);
                if (numBytes < 0) {
-                       debug_error(DEBUG, "error: avpicture_get_size. [%d x %d]\n", width, height);
+                       debug_error(DEBUG, "error: av_image_get_buffer_size. [%d x %d]\n", width, height);
                        ret = MMFILE_FORMAT_FAIL;
                        goto exception;
                }
 
                frame->frameData = mmfile_malloc(numBytes);
                if (NULL == frame->frameData) {
-                       debug_error(DEBUG, "error: avpicture_get_size. [%d]\n", numBytes);
+                       debug_error(DEBUG, "error: mmfile_malloc. [%d]\n", numBytes);
                        ret = MMFILE_FORMAT_FAIL;
                        goto exception;
                }
 
-               ret = avpicture_fill((AVPicture *)pFrameRGB, frame->frameData, AV_PIX_FMT_RGB24, width, height);
+               uint8_t *dst_data[4];
+               int dst_linesize[4];
+
+               ret = av_image_fill_arrays(dst_data, dst_linesize, frame->frameData, AV_PIX_FMT_RGB24, width, height, 1);
                if (ret < 0) {
                        debug_error(DEBUG, "error: avpicture_fill fail. errcode = 0x%08X\n", ret);
                        ret = MMFILE_FORMAT_FAIL;
@@ -847,7 +858,7 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
                        goto exception;
                }
 
-               ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, height, pFrameRGB->data, pFrameRGB->linesize);
+               ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, height, dst_data, dst_linesize);
                if (ret < 0) {
                        debug_error(DEBUG, "failed to convet image\n");
                        ret = MMFILE_FORMAT_FAIL;
@@ -866,22 +877,22 @@ int mmfile_format_read_frame_ffmpg(MMFileFormatContext *formatContext, unsigned
                frame->bCompressed = 0; /* false */
 
                if (pFrame)                     av_free(pFrame);
-               if (pFrameRGB)          av_free(pFrameRGB);
 
-               avcodec_close(pVideoCodecCtx);
+               avcodec_free_context(&pVideoCodecCtx);
 
                return MMFILE_FORMAT_SUCCESS;
        }
 
 
 exception:
-       if (pVideoCodecCtx)             avcodec_close(pVideoCodecCtx);
+       if (pVideoCodecCtx)     avcodec_free_context(&pVideoCodecCtx);
+
        if (frame->frameData) {
                mmfile_free(frame->frameData);
                frame->frameData = NULL;
        }
        if (pFrame)             av_free(pFrame);
-       if (pFrameRGB)  av_free(pFrameRGB);
+
        return ret;
 }
 
@@ -1036,11 +1047,10 @@ static void _dump_av_packet(AVPacket *pkt)
        debug_msg(RELEASE, " size: %d\n", pkt->size);
        debug_msg(RELEASE, " stream_index: %d\n", pkt->stream_index);
        debug_msg(RELEASE, " flags: 0x%08X, %s\n", pkt->flags, (pkt->flags & AV_PKT_FLAG_KEY) ? "Keyframe" : "_");
-       debug_msg(RELEASE, " duration: %d\n", pkt->duration);
+       debug_msg(RELEASE, " duration: %lld\n", pkt->duration);
        /*debug_msg(RELEASE, " destruct: %p\n", pkt->destruct);*/
        /*debug_msg(RELEASE, " priv: %p\n", pkt->priv);*/
        debug_msg(RELEASE, " pos: %lld\n", pkt->pos);
-       debug_msg(RELEASE, " convergence_duration: %lld\n", pkt->convergence_duration);
        debug_msg(RELEASE, "-------------------------------\n");
 }
 #endif
@@ -1058,7 +1068,7 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
        /*int stream_id = videoStream;*/
        int ret;
        int found = 0;
-       int i, v, len, got_picture;
+       int i, v, len;
        int retry = 0;
        int key_detected;
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
@@ -1099,14 +1109,13 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
 
        for (i = 0, v = 0, key_detected = 0, frame = first_frame; i < key_search_limit && v < frame_search_limit;) {
                av_init_packet(&pkt);
-               got_picture = 0;
 
                ret = av_read_frame(pFormatCtx, &pkt);
                if (ret < 0) {
                        debug_error(DEBUG, "read failed. (maybe EOF or broken)\n");
                        break;
                } else {
-                       if (avcodec_get_type(pFormatCtx->streams[pkt.stream_index]->codec->codec_id) == AVMEDIA_TYPE_VIDEO) {
+                       if (avcodec_get_type(pFormatCtx->streams[pkt.stream_index]->codecpar->codec_id) == AVMEDIA_TYPE_VIDEO) {
                                v++;
                                if ((pkt.flags & AV_PKT_FLAG_KEY) || (key_detected == 1))
                                {
@@ -1118,10 +1127,16 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
                                        i++;
                                        key_detected = 0;
 
-                                       len = avcodec_decode_video2(pCodecCtx, frame, &got_picture, &pkt);
-                                       if (len < 0) {
+                                       len = avcodec_send_packet(pCodecCtx, &pkt);
+                                       if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
+                                               debug_error(RELEASE, "Error while avcodec_send_packet[%2d]", len);
+                                               break;
+                                       }
+
+                                       len = avcodec_receive_frame(pCodecCtx, frame);
+                                       if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
                                                debug_warning(DEBUG, "Error while decoding frame %dth\n", i);
-                                       } else if (got_picture) {
+                                       } else if (len >= 0) {
                                                if (frame->key_frame) {
                                                        debug_msg(RELEASE, "key frame!\n");
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
@@ -1173,11 +1188,11 @@ static int _get_first_good_video_frame(AVFormatContext *pFormatCtx, AVCodecConte
                                }
                        }
                }
-               av_free_packet(&pkt);
+               av_packet_unref(&pkt);
        }
 
        /*free pkt after loop breaking*/
-       if (pkt.data) av_free_packet(&pkt);
+       if (pkt.data) av_packet_unref(&pkt);
 
        debug_msg(RELEASE, "found: %d, retry: %d\n", found, retry);
 
index 90ad04a..e79ffe9 100755 (executable)
@@ -22,6 +22,7 @@
 #include <libavformat/avformat.h>
 #include <libavcodec/avcodec.h>
 #include <libswscale/swscale.h>
+#include <libavutil/imgutils.h>
 
 #include <mm_types.h>
 #include "mm_file_debug.h"
@@ -31,9 +32,9 @@
 
 #define MILLION 1000000
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
-static void __save_frame(AVFrame *pFrame, int width, int height, int iFrame);
+static void __save_frame(uint8_t *const dst[], const int dstStride[], int width, int height, int iFrame);
 
-void __save_frame(AVFrame *pFrame, int width, int height, int iFrame)
+void __save_frame(uint8_t *const dst[], const int dstStride[], int width, int height, int iFrame)
 {
        FILE *pFile;
        char szFilename[32] = {0,};
@@ -50,7 +51,7 @@ void __save_frame(AVFrame *pFrame, int width, int height, int iFrame)
        fprintf(pFile, "P6\n%d %d\n255\n", width, height);
        /* Write pixel data */
        for (y = 0; y < height; y++)
-               fwrite(pFrame->data[0] + y * pFrame->linesize[0], 1, width * 3, pFile);
+               fwrite(dst[0] + y * dstStride[0], 1, width * 3, pFile);
 
        /* Close file */
        fclose(pFile);
@@ -378,15 +379,14 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
        int len = 0;
        int ret = MMFILE_FORMAT_SUCCESS;
        int videoStream = -1;
-       int key_detected = 0;
-       int got_picture = 0;
        int64_t pos = timestamp;
        bool find = false;
        bool first_seek = true;
        int64_t pts = 0;
        AVCodecContext *pVideoCodecCtx = NULL;
+       AVCodecParameters *pVideoCodecPar = NULL;
        AVCodec *pVideoCodec = NULL;
-       AVFrame *pFrame = NULL, *pFrameRGB = NULL;
+       AVFrame *pFrame = NULL;
        AVPacket packet;
 
        /* Retrieve stream information */
@@ -398,7 +398,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
 
        /* Find the first video stream */
        for (i = 0; i < pFormatCtx->nb_streams; i++) {
-               if (pFormatCtx->streams[i]->codec->codec_type == AVMEDIA_TYPE_VIDEO) {
+               if (pFormatCtx->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
                        videoStream = i;
                        break;
                }
@@ -411,21 +411,38 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
        }
 
        /* Get a pointer to the codec context for the video stream */
-       pVideoCodecCtx = pFormatCtx->streams[videoStream]->codec;
-       if (pVideoCodecCtx == NULL) {
+       pVideoCodecPar = pFormatCtx->streams[videoStream]->codecpar;
+       if (pVideoCodecPar == NULL) {
                debug_error(DEBUG, "invalid param\n");
                ret = MMFILE_FORMAT_FAIL;
                goto exception;
        }
 
        /* Find the decoder for the video stream */
-       pVideoCodec = avcodec_find_decoder(pVideoCodecCtx->codec_id);
+       pVideoCodec = avcodec_find_decoder(pVideoCodecPar->codec_id);
        if (pVideoCodec == NULL) {
                debug_error(DEBUG, "error : Unsupported codec");
                ret = MMFILE_FORMAT_FAIL;
                goto exception; /* Codec not found */
        }
 
+       pVideoCodecCtx = avcodec_alloc_context3(pVideoCodec);
+       if (NULL == pVideoCodecCtx) {
+               debug_error(DEBUG, "error: pVideoCodecCtx == NULL\n");
+               ret = MMFILE_FORMAT_FAIL;
+               goto exception;
+       }
+
+       ret = avcodec_parameters_to_context(pVideoCodecCtx, pVideoCodecPar);
+       if (ret < 0) {
+               debug_error(DEBUG, "error: avcodec_parameters_to_context\n");
+               ret = MMFILE_FORMAT_FAIL;
+               goto exception;
+       }
+
+       /*set workaround bug flag*/
+       //pVideoCodecCtx->workaround_bugs = FF_BUG_AUTODETECT;
+
        /* Open codec */
        pVideoCodecCtx->thread_type = 0;
        pVideoCodecCtx->thread_count = 0;
@@ -444,14 +461,6 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                goto exception;
        }
 
-       /* Allocate an AVFrame structure */
-       pFrameRGB = av_frame_alloc();
-       if (pFrameRGB == NULL) {
-               debug_error(DEBUG, "error: pFrameRGB is NULL\n");
-               ret = MMFILE_FORMAT_FAIL;
-               goto exception;
-       }
-
        /* Seeking */
        AVStream *pStream = pFormatCtx->streams[videoStream];
        double duration = (double) pFormatCtx->duration / AV_TIME_BASE;
@@ -489,7 +498,6 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
        av_init_packet(&packet);
 
        while (av_read_frame(pFormatCtx, &packet) >= 0) {
-               got_picture = 0;
 
                /* Is this a packet from the video stream? */
                if (packet.stream_index == videoStream) {
@@ -498,20 +506,25 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                        #endif
 
                        /* Decode video frame*/
-                       len = avcodec_decode_video2(pVideoCodecCtx, pFrame, &got_picture, &packet);
-                       if (len < 0) {
-                               debug_warning(DEBUG, "Error while decoding frame");
-                       } else if ((packet.flags & AV_PKT_FLAG_KEY) || (key_detected == 1)) {
+                       len = avcodec_send_packet(pVideoCodecCtx, &packet);
+                       if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
+                               debug_error(RELEASE, "Error while avcodec_send_packet[%2d]", len);
+                               break;
+                       }
 
-                               key_detected = 0;
+                       len = avcodec_receive_frame(pVideoCodecCtx, pFrame);
+                       debug_msg(RELEASE, "avcodec_receive_frame[%2d]", len);
+                       if (len < 0 && len != AVERROR(EAGAIN) && len != AVERROR_EOF) {
+                               debug_warning(DEBUG, "Error while avcodec_receive_frame");
+                       } else if (len >= 0) {
+                               if ((packet.flags & AV_PKT_FLAG_KEY) ) {
 
-                               if (first_seek || !is_accurate) {
-                                       /* This is first seeking or not accurate mode.
-                                       Sometimes flag is AV_PKT_FLAG_KEY but got_picture is NULL.
-                                       first_seek is used when accurate mode and when time stamp's frame is not key frame.
-                                       Go back to previousto Key frame and decode frame until time stamp's frame*/
+                                       if (first_seek || !is_accurate) {
+                                               /* This is first seeking or not accurate mode.
+                                               Sometimes flag is AV_PKT_FLAG_KEY but got_picture is NULL.
+                                               first_seek is used when accurate mode and when time stamp's frame is not key frame.
+                                               Go back to previousto Key frame and decode frame until time stamp's frame*/
 
-                                       if (got_picture) {
                                                if (pFrame->key_frame) {
                                                        debug_msg(RELEASE, "find Video Stream+++++++Find key frame");
                                                } else {
@@ -520,42 +533,40 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
 
                                                /*eventhough decoded pFrame is not key frame, if packet.flags is AV_PKT_FLAG_KEY then can extract frame*/
                                                find = true;
+                                       }
+                               } else {
+                                       if (is_accurate) {
+                                               if (first_seek) {
+                                                       pts = (packet.pts == (int64_t)AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
+                                                       first_seek = false;
 
-                                       } else {
-                                               debug_msg(RELEASE, "find Video Stream+++++++Find key but no frame");
-                                               key_detected = 1;
+                                                       av_seek_frame(pFormatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
+                                               } else {
+                                                       tmpPts = (packet.pts == (int64_t)AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
+                                                       if (pts == tmpPts)
+                                                               find = true;
+                                               }
                                        }
                                }
                        } else {
-                               if (is_accurate) {
-                                       if (first_seek) {
-                                               pts = (packet.pts == (int64_t)AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
-                                               first_seek = false;
-
-                                               av_seek_frame(pFormatCtx, -1, pos, AVSEEK_FLAG_BACKWARD);
-                                       } else {
-                                               tmpPts = (packet.pts == (int64_t)AV_NOPTS_VALUE) ? (packet.dts * av_q2d(pStream->time_base)) : packet.pts;
-                                               if (pts == tmpPts)
-                                                       find = true;
-                                       }
-                               }
+                               debug_msg(RELEASE, "decode not completed.\n");
                        }
 
-                       if (find && got_picture) {
+                       if (find) {
                                break;
                        }
                }
 
                /* Free the packet that was allocated by av_read_frame*/
-               av_free_packet(&packet);
+               av_packet_unref(&packet);
                av_init_packet(&packet);
        }
 
        /*free pkt after loop breaking*/
-       av_free_packet(&packet);
+       av_packet_unref(&packet);
 
        /* Did we get a video frame?*/
-       if (got_picture && find) {
+       if (find) {
 
                debug_msg(RELEASE, "Find Frame");
 
@@ -568,7 +579,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                        *height = pVideoCodecCtx->height;
                }
 
-               *size = avpicture_get_size(AV_PIX_FMT_RGB24, *width, *height);
+               *size = av_image_get_buffer_size(AV_PIX_FMT_RGB24, *width, *height, 1);
 
                if (*size > 0)
                        *frame = mmfile_malloc(*size);
@@ -584,7 +595,9 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                debug_msg(RELEASE, "height : %d", *height);
                debug_msg(RELEASE, "frame : %p", *frame);
 
-               ret = avpicture_fill((AVPicture *)pFrameRGB, *frame, AV_PIX_FMT_RGB24, *width, *height);
+               uint8_t *dst_data[4];
+               int dst_linesize[4];
+               ret = av_image_fill_arrays(dst_data, dst_linesize, *frame, AV_PIX_FMT_RGB24, *width, *height, 1);
                if (ret < 0) {
                        debug_error(DEBUG, "error: avpicture_fill fail. errcode = 0x%08X\n", ret);
                        ret = MMFILE_FORMAT_FAIL;
@@ -593,8 +606,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
 
                struct SwsContext *img_convert_ctx = NULL;
 
-               img_convert_ctx = sws_getContext(*width, *height, pVideoCodecCtx->pix_fmt,
-                                               *width, *height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
+               img_convert_ctx = sws_getContext(*width, *height, pVideoCodecCtx->pix_fmt, *width, *height, AV_PIX_FMT_RGB24, SWS_BICUBIC, NULL, NULL, NULL);
 
                if (NULL == img_convert_ctx) {
                        debug_error(DEBUG, "failed to get img convet ctx\n");
@@ -602,8 +614,7 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                        goto exception;
                }
 
-               ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize,
-                                       0, *height, pFrameRGB->data, pFrameRGB->linesize);
+               ret = sws_scale(img_convert_ctx, (const uint8_t * const *)pFrame->data, pFrame->linesize, 0, *height, dst_data, dst_linesize);
                if (ret < 0) {
                        debug_error(DEBUG, "failed to convet image\n");
                        sws_freeContext(img_convert_ctx);
@@ -616,17 +627,16 @@ static int __mmfile_get_frame(AVFormatContext *pFormatCtx, int64_t timestamp, bo
                img_convert_ctx = NULL;
 
 #ifdef MMFILE_FORMAT_DEBUG_DUMP
-               __save_frame(pFrameRGB, pVideoCodecCtx->width, pVideoCodecCtx->height, (int)(pos / 1000));
+               __save_frame(dst_data, dst_linesize, pVideoCodecCtx->width, pVideoCodecCtx->height, (int)(pos / 1000));
 #endif
        } else {
-               debug_error(DEBUG, "Not Found Proper Frame[%d][%d]", got_picture, find);
+               debug_error(DEBUG, "Not Found Proper Frame[%d]", find);
                ret = MMFILE_FORMAT_FAIL;
                goto exception;
        }
 
        if (pFrame)                     av_free(pFrame);
-       if (pFrameRGB)          av_free(pFrameRGB);
-       if (pVideoCodecCtx)     avcodec_close(pVideoCodecCtx);
+       if (pVideoCodecCtx)     avcodec_free_context(&pVideoCodecCtx);
 
        return MMFILE_FORMAT_SUCCESS;
 
@@ -636,8 +646,7 @@ exception:
                *frame = NULL;
        }
        if (pFrame)                     av_free(pFrame);
-       if (pFrameRGB)          av_free(pFrameRGB);
-       if (pVideoCodecCtx)     avcodec_close(pVideoCodecCtx);
+       if (pVideoCodecCtx)     avcodec_free_context(&pVideoCodecCtx);
 
        return ret;
 }
index 4c28c1c..f45c449 100755 (executable)
@@ -1,6 +1,6 @@
 Name:      libmm-fileinfo
 Summary:    Media Fileinfo
-Version:    0.6.65
+Version:    0.6.66
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0