Ignore:
Timestamp:
Jan 18, 2011 7:07:10 PM (11 years ago)
Author:
gah
Message:
 
File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/blt4/src/objects/RpVideo.c

    r1932 r2044  
    1919#include <string.h>
    2020
    21 #include <libavcodec/avcodec.h>
    22 #include <libavformat/avformat.h>
    23 #include <libswscale/swscale.h>
     21#include "config.h"
     22
     23#ifdef HAVE_FFMPEG_AVCODEC_H
     24# include <ffmpeg/avcodec.h>
     25#endif
     26
     27#ifdef HAVE_LIBAVCODEC_AVCODEC_H
     28# include <libavcodec/avcodec.h>
     29#endif
     30
     31#ifdef HAVE_FFMPEG_AVFORMAT_H
     32# include <ffmpeg/avformat.h>
     33#endif
     34
     35#ifdef HAVE_LIBAVFORMAT_AVFORMAT_H
     36# include <libavformat/avformat.h>
     37#endif
     38
     39#ifdef HAVE_FFMPEG_AVUTIL_H
     40# include <ffmpeg/avutil.h>
     41#endif
     42
     43#ifdef HAVE_LIBAVUTIL_AVUTIL_H
     44# include <libavutil/avutil.h>
     45#endif
     46
     47#ifdef HAVE_FFMPEG_SWSCALE_H
     48# include <ffmpeg/swscale.h>
     49#endif
     50
     51#ifdef HAVE_LIBSWSCALE_SWSCALE_H
     52# include <libswscale/swscale.h>
     53#endif
    2454
    2555#include "RpVideo.h"
     
    5383    char mode[64];
    5484    char fmt[64];
     85    int lastframe;
    5586
    5687    /* tmp buffer to give images back to user */
     
    124155    *vid->mode = '\0';
    125156    *vid->fmt = '\0';
     157    vid->lastframe = 0;
    126158
    127159    vid->img = NULL;
     
    141173    int fnlen = 0;
    142174    int err = 0;
     175    int lastframe = 0;
    143176
    144177    if (fileName == NULL) {
     
    176209            return err;
    177210        }
     211
     212        VideoFindLastFrame(vidPtr,&lastframe);
     213        vidPtr->lastframe = lastframe;
    178214    } else if (*mode == 'w') {
    179215        /* we're now in "input" mode */
     
    186222    return 0;
    187223}
     224
     225/*
     226 * ------------------------------------------------------------------------
     227 *  VideoFindLastFrame()
     228 *
     229 *  Find the last readable frame.
     230 * ------------------------------------------------------------------------
     231 */
     232int
     233VideoFindLastFrame(vidPtr,lastframe)
     234    VideoObj *vidPtr;
     235    int *lastframe;
     236{
     237    int f = 0;
     238    int nframe = 0;
     239    int cur = 0;
     240    AVStream *vstreamPtr;
     241
     242    if (vidPtr == NULL) {
     243        return -1;
     244    }
     245
     246    if (lastframe == NULL) {
     247        return -1;
     248    }
     249
     250    if (VideoModeRead(vidPtr) != 0) {
     251        return -1;
     252    }
     253
     254    // calculate an estimate of the last frame
     255    vstreamPtr = vidPtr->pFormatCtx->streams[vidPtr->videoStream];
     256    nframe = VideoTime2Frame(vstreamPtr,
     257        vstreamPtr->start_time + vstreamPtr->duration);
     258
     259    // get the real last readable frame
     260    // is 50 frames far enough to go back
     261    // to be outside of the last key frame?
     262    f = vidPtr->frameNumber;
     263    cur = VideoGoToN(vidPtr,nframe-50);
     264    while (cur != nframe) {
     265        cur = nframe;
     266        nframe = VideoGoNext(vidPtr);
     267    }
     268    *lastframe = nframe;
     269    VideoGoToN(vidPtr,f);
     270
     271    return 0;
     272}
     273
    188274
    189275/*
     
    619705                    global_video_pkt_pts = packet.pts;
    620706
    621                     // avcodec_decode_video(vcodecCtx, vidPtr->pFrameYUV,
    622                     //     &frameFinished, packet.data, packet.size);
    623 
    624                     // packet.flags = PKT_FLAG_KEY;
    625                     avcodec_decode_video2(vcodecCtx, vidPtr->pFrameYUV,
    626                         &frameFinished, &packet);
    627 
    628                     // avcodec_decode_video2(_pCodecCtx, _pFrame, &frameFinished,
    629                     //                                   &_packet);
     707                    avcodec_decode_video(vcodecCtx, vidPtr->pFrameYUV,
     708                        &frameFinished, packet.data, packet.size);
     709
     710                    // avcodec_decode_video2(vcodecCtx, vidPtr->pFrameYUV,
     711                    //    &frameFinished, &packet);
    630712
    631713                    if (packet.dts == AV_NOPTS_VALUE
     
    686768/*
    687769 * ------------------------------------------------------------------------
    688  *  VideoInitCmd()
     770 *  VideoInit()
    689771 *
    690772 *  Implements the body of the _ffmpeg_init method in the "video" class.
     
    694776 */
    695777VideoObj *
    696 VideoInitCmd()
     778VideoInit()
    697779{
    698780    /*
     
    708790/*
    709791 * ------------------------------------------------------------------------
    710  *  VideoCleanupCmd()
     792 *  VideoCleanup()
    711793 *
    712794 *  Implements the body of the _ffmpeg_cleanup method in the "video" class.
     
    716798 */
    717799int
    718 VideoCleanupCmd(vidPtr)
     800VideoCleanup(vidPtr)
    719801    VideoObj *vidPtr;
    720802{
     
    744826/*
    745827 * ------------------------------------------------------------------------
    746  *  VideoSizeCmd()
     828 *  VideoSize()
    747829 *
    748830 *  Implements the body of the "size" method in the "video" class.
     
    751833 */
    752834int
    753 VideoSizeCmd(vidPtr, width, height)
     835VideoSize(vidPtr, width, height)
    754836    VideoObj *vidPtr;
    755837    int *width;
     
    781863/*
    782864 * ------------------------------------------------------------------------
    783  *  VideoGoCmd()
     865 *  VideoGo()
    784866 *
    785867 *  Implements the body of the "go" method in the "video" class.
     
    796878    VideoObj *vidPtr;
    797879{
    798     return VideoGoPlusMinusN(vidPtr,1);
     880    int nabs;
     881
     882    if (vidPtr == NULL) {
     883        return -1;
     884    }
     885
     886    nabs = vidPtr->frameNumber + 1;
     887    return VideoGoToN(vidPtr, nabs);
    799888}
    800889
     
    819908    int n;
    820909{
    821     int nrel, nabs, seekFlags, gotframe;
     910    int nrel, nabs, seekFlags, gotframe, t;
    822911    int64_t nseek;
    823912    AVCodecContext *vcodecCtx;
     
    855944        vstreamPtr = vidPtr->pFormatCtx->streams[vidPtr->videoStream];
    856945        nseek = VideoFrame2Time(vstreamPtr, nabs);
     946        // not sure why it is checking against the number 100
    857947        if (nseek > 100) {
    858948            nseek -= 100;
     
    865955            nseek, seekFlags);
    866956
     957        // this doesn't seem to give me back the true frame number
     958        // feels like it is more of a reverse of the VideoFrame2Time call
     959        // because vidPtr->frameNumber always equals nabs
    867960        vidPtr->frameNumber = VideoTime2Frame(vstreamPtr, nseek);
    868961        vidPtr->atEnd = 0;
     962
     963        /* read the frame to figure out what the frame number is */
     964        VideoNextFrame(vidPtr);
    869965
    870966        /* then, move forward until we reach the desired frame */
     
    877973        /* get at least one frame, unless we're done or at the beginning*/
    878974        if (!gotframe && !vidPtr->atEnd) {
    879             VideoNextFrame(vidPtr);
     975            if (vidPtr->frameNumber > nabs) {
     976                // we are probably at a key frame, just past
     977                // the requested frame and need to seek backwards.
     978                VideoGoToN(vidPtr,n);
     979            } else {
     980                VideoNextFrame(vidPtr);
     981            }
    880982        }
    881983    }
     
    894996/*
    895997 * ------------------------------------------------------------------------
    896  *  VideoGetCmd()
     998 *  VideoGet()
    897999 *
    8981000 *  Implements the body of the "get" method in the "video" class.
     
    10071109                free(vidPtr->img);
    10081110                VideoAllocImgBuffer(vidPtr,iw,ih);
    1009             } else {
    1010                 // image buffer is the correct size
    1011                 // do nothing
    10121111            }
    10131112        }
     
    10241123
    10251124int
    1026 VideoGetFrameRate (vidPtr, fr)
     1125VideoFrameRate (vidPtr, fr)
    10271126    VideoObj *vidPtr;
    10281127    double *fr;
     
    10511150    // as frames per second.
    10521151    *fr = av_q2d(vstreamPtr->r_frame_rate);
     1152
     1153    return 0;
     1154}
     1155
     1156int
     1157VideoFileName (vidPtr, fname)
     1158    VideoObj *vidPtr;
     1159    const char **fname;
     1160{
     1161    AVStream *vstreamPtr;
     1162
     1163    if (vidPtr == NULL) {
     1164        return -1;
     1165    }
     1166
     1167    if (fname == NULL) {
     1168        return -1;
     1169    }
     1170
     1171    if (vidPtr->pFormatCtx == NULL) {
     1172        // vidPtr->pFormatCtx is NULL, video not open
     1173        return -1;
     1174    }
     1175
     1176    *fname = vidPtr->fileName;
     1177
     1178    return 0;
     1179}
     1180
     1181int
     1182VideoPixelAspectRatio (vidPtr, num, den)
     1183    VideoObj *vidPtr;
     1184    int *num;
     1185    int *den;
     1186{
     1187    AVCodecContext *vcodecCtx;
     1188
     1189    if (vidPtr == NULL) {
     1190        return -1;
     1191    }
     1192
     1193    if ((num == NULL) || (den == NULL)) {
     1194        return -1;
     1195    }
     1196
     1197    if (vidPtr->pFormatCtx == NULL) {
     1198        // vidPtr->pFormatCtx is NULL, video not open
     1199        return -1;
     1200    }
     1201
     1202    vcodecCtx = vidPtr->pFormatCtx->streams[vidPtr->videoStream]->codec;
     1203
     1204    *num = vcodecCtx->sample_aspect_ratio.num;
     1205    *den = vcodecCtx->sample_aspect_ratio.den;
     1206
     1207    return 0;
     1208}
     1209
     1210int
     1211VideoDisplayAspectRatio (vidPtr, num, den)
     1212    VideoObj *vidPtr;
     1213    int *num;
     1214    int *den;
     1215{
     1216    AVCodecContext *vcodecCtx;
     1217    int width = 0;
     1218    int height = 0;
     1219    int64_t gcd = 0;
     1220    int64_t gcd2 = 0;
     1221
     1222    if (vidPtr == NULL) {
     1223        return -1;
     1224    }
     1225
     1226    if ((num == NULL) || (den == NULL)) {
     1227        return -1;
     1228    }
     1229
     1230    if (vidPtr->pFormatCtx == NULL) {
     1231        // vidPtr->pFormatCtx is NULL, video not open
     1232        return -1;
     1233    }
     1234
     1235    VideoSize(vidPtr, &width, &height);
     1236    VideoPixelAspectRatio(vidPtr, num, den);
     1237
     1238    width = (*num)*width;
     1239    height = (*den)*height;
     1240    gcd = av_gcd(FFABS(width), FFABS(height));
     1241
     1242    *num = width/gcd;
     1243    *den = height/gcd;
     1244
     1245    if (*den == 0) {
     1246        *num = 0;
     1247        *den = 1;
     1248    }
    10531249
    10541250    return 0;
     
    11221318    int *pos;
    11231319{
    1124     int nframe = -1;
    11251320    AVStream *vstreamPtr;
    11261321
     
    11371332    }
    11381333
    1139     if (vidPtr->pFormatCtx) {
    1140         vstreamPtr = vidPtr->pFormatCtx->streams[vidPtr->videoStream];
    1141         nframe = VideoTime2Frame(vstreamPtr,
    1142             vstreamPtr->start_time + vstreamPtr->duration);
    1143     }
    1144 
    1145     *pos = nframe;
     1334    *pos = vidPtr->lastframe;
    11461335    return 0;
    11471336}
     
    11501339///*
    11511340// * ------------------------------------------------------------------------
    1152 // *  VideoPutCmd()
     1341// *  VideoPut()
    11531342// *
    11541343// *  Implements the body of the "put" method in the "video" class.
     
    11581347// */
    11591348//int
    1160 //VideoPutCmd(cdata, interp, argc, argv)
     1349//VideoPut(cdata, interp, argc, argv)
    11611350//    ClientData cdata;      /* not used */
    11621351//    Tcl_Interp *interp;    /* interpreter */
Note: See TracChangeset for help on using the changeset viewer.