329
322
{"genpts", "generate pts", 0, FF_OPT_TYPE_CONST, AVFMT_FLAG_GENPTS, INT_MIN, INT_MAX, D, "fflags"},
330
323
{"track", " set the track number", OFFSET(track), FF_OPT_TYPE_INT, DEFAULT, 0, INT_MAX, E},
331
324
{"year", "set the year", OFFSET(year), FF_OPT_TYPE_INT, DEFAULT, INT_MIN, INT_MAX, E},
332
{"analyzeduration", NULL, OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D},
325
{"analyzeduration", "how many microseconds are analyzed to estimate duration", OFFSET(max_analyze_duration), FF_OPT_TYPE_INT, 3*AV_TIME_BASE, 0, INT_MAX, D},
326
{"cryptokey", "decryption key", OFFSET(key), FF_OPT_TYPE_BINARY, 0, 0, 0, D},
327
{"indexmem", "max memory used for timestamp index (per stream)", OFFSET(max_index_size), FF_OPT_TYPE_INT, 1<<20, 0, INT_MAX, D},
328
{"rtbufsize", "max memory used for buffering real-time frames", OFFSET(max_picture_buffer), FF_OPT_TYPE_INT, 3041280, 0, INT_MAX, D}, /* defaults to 1s of 15fps 352x288 YUYV422 video */
634
static int64_t lsb2full(int64_t lsb, int64_t last_ts, int lsb_bits){
635
int64_t mask = lsb_bits < 64 ? (1LL<<lsb_bits)-1 : -1LL;
636
int64_t delta= last_ts - mask/2;
637
return ((lsb - delta)&mask) + delta;
608
static void update_initial_timestamps(AVFormatContext *s, int stream_index,
609
int64_t dts, int64_t pts)
611
AVStream *st= s->streams[stream_index];
612
AVPacketList *pktl= s->packet_buffer;
614
if(st->first_dts != AV_NOPTS_VALUE || dts == AV_NOPTS_VALUE)
617
st->first_dts= dts - st->cur_dts;
620
for(; pktl; pktl= pktl->next){
621
if(pktl->pkt.stream_index != stream_index)
623
//FIXME think more about this check
624
if(pktl->pkt.pts != AV_NOPTS_VALUE && pktl->pkt.pts == pktl->pkt.dts)
625
pktl->pkt.pts += st->first_dts;
627
if(pktl->pkt.dts != AV_NOPTS_VALUE)
628
pktl->pkt.dts += st->first_dts;
630
if(st->start_time == AV_NOPTS_VALUE && pktl->pkt.pts != AV_NOPTS_VALUE)
631
st->start_time= pktl->pkt.pts;
633
if (st->start_time == AV_NOPTS_VALUE)
634
st->start_time = pts;
637
static void update_initial_durations(AVFormatContext *s, AVStream *st, AVPacket *pkt)
639
AVPacketList *pktl= s->packet_buffer;
641
assert(pkt->duration && !st->cur_dts);
643
for(; pktl; pktl= pktl->next){
644
if(pktl->pkt.stream_index != pkt->stream_index)
646
if(pktl->pkt.pts == pktl->pkt.dts && pktl->pkt.dts == AV_NOPTS_VALUE
647
&& !pktl->pkt.duration){
648
pktl->pkt.pts= pktl->pkt.dts= st->cur_dts;
649
st->cur_dts += pkt->duration;
650
pktl->pkt.duration= pkt->duration;
640
656
static void compute_pkt_fields(AVFormatContext *s, AVStream *st,
641
657
AVCodecParserContext *pc, AVPacket *pkt)
643
int num, den, presentation_delayed;
644
/* handle wrapping */
645
if(st->cur_dts != AV_NOPTS_VALUE){
659
int num, den, presentation_delayed, delay, i;
662
if(pkt->pts != AV_NOPTS_VALUE && pkt->dts != AV_NOPTS_VALUE && pkt->dts > pkt->pts && st->pts_wrap_bits<63
663
/*&& pkt->dts-(1LL<<st->pts_wrap_bits) < pkt->pts*/){
664
pkt->dts -= 1LL<<st->pts_wrap_bits;
667
if (pkt->duration == 0) {
668
compute_frame_duration(&num, &den, st, pc, pkt);
670
pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
672
if(st->cur_dts == 0 && pkt->duration != 0)
673
update_initial_durations(s, st, pkt);
677
/* correct timestamps with byte offset if demuxers only have timestamps
678
on packet boundaries */
679
if(pc && st->need_parsing == AVSTREAM_PARSE_TIMESTAMPS && pkt->size){
680
/* this will estimate bitrate based on this frame's duration and size */
681
offset = av_rescale(pc->offset, pkt->duration, pkt->size);
646
682
if(pkt->pts != AV_NOPTS_VALUE)
647
pkt->pts= lsb2full(pkt->pts, st->cur_dts, st->pts_wrap_bits);
648
684
if(pkt->dts != AV_NOPTS_VALUE)
649
pkt->dts= lsb2full(pkt->dts, st->cur_dts, st->pts_wrap_bits);
652
if (pkt->duration == 0) {
653
compute_frame_duration(&num, &den, st, pc, pkt);
655
pkt->duration = av_rescale(1, num * (int64_t)st->time_base.den, den * (int64_t)st->time_base.num);
659
if(is_intra_only(st->codec))
660
pkt->flags |= PKT_FLAG_KEY;
662
/* do we have a video B frame ? */
688
/* do we have a video B-frame ? */
689
delay= st->codec->has_b_frames;
663
690
presentation_delayed = 0;
664
if (st->codec->codec_type == CODEC_TYPE_VIDEO) {
665
/* XXX: need has_b_frame, but cannot get it if the codec is
667
if (( st->codec->codec_id == CODEC_ID_H264
668
|| st->codec->has_b_frames) &&
669
pc && pc->pict_type != FF_B_TYPE)
670
presentation_delayed = 1;
671
/* this may be redundant, but it shouldnt hurt */
672
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
673
presentation_delayed = 1;
691
/* XXX: need has_b_frame, but cannot get it if the codec is
694
pc && pc->pict_type != FF_B_TYPE)
695
presentation_delayed = 1;
696
/* This may be redundant, but it should not hurt. */
697
if(pkt->dts != AV_NOPTS_VALUE && pkt->pts != AV_NOPTS_VALUE && pkt->pts > pkt->dts)
698
presentation_delayed = 1;
676
700
if(st->cur_dts == AV_NOPTS_VALUE){
677
if(presentation_delayed) st->cur_dts = -pkt->duration;
678
else st->cur_dts = 0;
701
st->cur_dts = 0; //FIXME maybe set it to 0 during init
681
704
// av_log(NULL, AV_LOG_DEBUG, "IN delayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64" st:%d pc:%p\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts, pkt->stream_index, pc);
682
705
/* interpolate PTS and DTS if they are not present */
683
if (presentation_delayed) {
684
/* DTS = decompression time stamp */
685
/* PTS = presentation time stamp */
686
if (pkt->dts == AV_NOPTS_VALUE) {
687
/* if we know the last pts, use it */
688
if(st->last_IP_pts != AV_NOPTS_VALUE)
689
st->cur_dts = pkt->dts = st->last_IP_pts;
707
if (presentation_delayed) {
708
/* DTS = decompression timestamp */
709
/* PTS = presentation timestamp */
710
if (pkt->dts == AV_NOPTS_VALUE)
711
pkt->dts = st->last_IP_pts;
712
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts);
713
if (pkt->dts == AV_NOPTS_VALUE)
691
714
pkt->dts = st->cur_dts;
693
st->cur_dts = pkt->dts;
695
/* this is tricky: the dts must be incremented by the duration
696
of the frame we are displaying, i.e. the last I or P frame */
697
if (st->last_IP_duration == 0)
698
st->cur_dts += pkt->duration;
700
st->cur_dts += st->last_IP_duration;
701
st->last_IP_duration = pkt->duration;
702
st->last_IP_pts= pkt->pts;
703
/* cannot compute PTS if not present (we can compute it only
704
by knowing the futur */
705
} else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
706
if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
707
int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts);
708
int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
709
if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
710
pkt->pts += pkt->duration;
711
// av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
716
/* this is tricky: the dts must be incremented by the duration
717
of the frame we are displaying, i.e. the last I- or P-frame */
718
if (st->last_IP_duration == 0)
719
st->last_IP_duration = pkt->duration;
720
st->cur_dts = pkt->dts + st->last_IP_duration;
721
st->last_IP_duration = pkt->duration;
722
st->last_IP_pts= pkt->pts;
723
/* cannot compute PTS if not present (we can compute it only
724
by knowing the future */
725
} else if(pkt->pts != AV_NOPTS_VALUE || pkt->dts != AV_NOPTS_VALUE || pkt->duration){
726
if(pkt->pts != AV_NOPTS_VALUE && pkt->duration){
727
int64_t old_diff= FFABS(st->cur_dts - pkt->duration - pkt->pts);
728
int64_t new_diff= FFABS(st->cur_dts - pkt->pts);
729
if(old_diff < new_diff && old_diff < (pkt->duration>>3)){
730
pkt->pts += pkt->duration;
731
// av_log(NULL, AV_LOG_DEBUG, "id:%d old:%"PRId64" new:%"PRId64" dur:%d cur:%"PRId64" size:%d\n", pkt->stream_index, old_diff, new_diff, pkt->duration, st->cur_dts, pkt->size);
715
/* presentation is not delayed : PTS and DTS are the same */
716
if (pkt->pts == AV_NOPTS_VALUE) {
717
if (pkt->dts == AV_NOPTS_VALUE) {
735
/* presentation is not delayed : PTS and DTS are the same */
736
if(pkt->pts == AV_NOPTS_VALUE)
738
update_initial_timestamps(s, pkt->stream_index, pkt->pts, pkt->pts);
739
if(pkt->pts == AV_NOPTS_VALUE)
718
740
pkt->pts = st->cur_dts;
719
pkt->dts = st->cur_dts;
722
st->cur_dts = pkt->dts;
726
st->cur_dts = pkt->pts;
727
741
pkt->dts = pkt->pts;
729
st->cur_dts += pkt->duration;
731
// av_log(NULL, AV_LOG_DEBUG, "OUTdelayed:%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, pkt->pts, pkt->dts, st->cur_dts);
742
st->cur_dts = pkt->pts + pkt->duration;
746
if(pkt->pts != AV_NOPTS_VALUE){
747
st->pts_buffer[0]= pkt->pts;
748
for(i=1; i<delay+1 && st->pts_buffer[i] == AV_NOPTS_VALUE; i++)
749
st->pts_buffer[i]= (i-delay-1) * pkt->duration;
750
for(i=0; i<delay && st->pts_buffer[i] > st->pts_buffer[i+1]; i++)
751
FFSWAP(int64_t, st->pts_buffer[i], st->pts_buffer[i+1]);
752
if(pkt->dts == AV_NOPTS_VALUE)
753
pkt->dts= st->pts_buffer[0];
755
update_initial_timestamps(s, pkt->stream_index, pkt->dts, pkt->pts); // this should happen on the first packet
757
if(pkt->dts > st->cur_dts)
758
st->cur_dts = pkt->dts;
761
// av_log(NULL, AV_LOG_ERROR, "OUTdelayed:%d/%d pts:%"PRId64", dts:%"PRId64" cur_dts:%"PRId64"\n", presentation_delayed, delay, pkt->pts, pkt->dts, st->cur_dts);
733
763
/* update flags */
764
if(is_intra_only(st->codec))
765
pkt->flags |= PKT_FLAG_KEY;
736
/* key frame computation */
737
switch(st->codec->codec_type) {
738
case CODEC_TYPE_VIDEO:
768
/* keyframe computation */
739
769
if (pc->pict_type == FF_I_TYPE)
740
770
pkt->flags |= PKT_FLAG_KEY;
742
case CODEC_TYPE_AUDIO:
743
pkt->flags |= PKT_FLAG_KEY;
1794
1802
else return ((int[]){24,30,60,12,15})[i-60*12]*1000*12;
1798
* Read packets of a media file to get stream information. This
1799
* is useful for file formats with no headers such as MPEG. This
1800
* function also computes the real frame rate in case of mpeg2 repeat
1802
* The logical file position is not changed by this function;
1803
* examined packets may be buffered for later processing.
1805
* @param ic media file handle
1806
* @return >=0 if OK. AVERROR_xxx if error.
1807
* @todo let user decide somehow what information is needed so we dont waste time geting stuff the user doesnt need
1806
* Is the time base unreliable.
1807
* This is a heuristic to balance between quick acceptance of the values in
1808
* the headers vs. some extra checks.
1809
* Old DivX and Xvid often have nonsense timebases like 1fps or 2fps.
1810
* MPEG-2 commonly misuses field repeat flags to store different framerates.
1811
* And there are "variable" fps files this needs to detect as well.
1813
static int tb_unreliable(AVCodecContext *c){
1814
if( c->time_base.den >= 101L*c->time_base.num
1815
|| c->time_base.den < 5L*c->time_base.num
1816
/* || c->codec_tag == ff_get_fourcc("DIVX")
1817
|| c->codec_tag == ff_get_fourcc("XVID")*/
1818
|| c->codec_id == CODEC_ID_MPEG2VIDEO)
1809
1823
int av_find_stream_info(AVFormatContext *ic)
1811
1825
int i, count, ret, read_size, j;
1813
1827
AVPacket pkt1, *pkt;
1814
AVPacketList *pktl=NULL, **ppktl;
1815
1828
int64_t last_dts[MAX_STREAMS];
1816
1829
int duration_count[MAX_STREAMS]={0};
1817
1830
double (*duration_error)[MAX_STD_TIMEBASES];
1818
offset_t old_offset = url_ftell(&ic->pb);
1831
offset_t old_offset = url_ftell(ic->pb);
1832
int64_t codec_info_duration[MAX_STREAMS]={0};
1833
int codec_info_nb_frames[MAX_STREAMS]={0};
1834
AVProbeData probe_data[MAX_STREAMS];
1835
int codec_identified[MAX_STREAMS]={0};
1820
1837
duration_error = av_mallocz(MAX_STREAMS * sizeof(*duration_error));
1821
if (!duration_error) return AVERROR_NOMEM;
1838
if (!duration_error) return AVERROR(ENOMEM);
1823
1840
for(i=0;i<ic->nb_streams;i++) {
1824
1841
st = ic->streams[i];
2543
2555
ret = s->oformat->write_trailer(s);
2546
ret=url_ferror(&s->pb);
2558
ret=url_ferror(s->pb);
2547
2559
for(i=0;i<s->nb_streams;i++)
2548
2560
av_freep(&s->streams[i]->priv_data);
2549
2561
av_freep(&s->priv_data);
2565
void av_program_add_stream_index(AVFormatContext *ac, int progid, unsigned int idx)
2568
AVProgram *program=NULL;
2571
for(i=0; i<ac->nb_programs; i++){
2572
if(ac->programs[i]->id != progid)
2574
program = ac->programs[i];
2575
for(j=0; j<program->nb_stream_indexes; j++)
2576
if(program->stream_index[j] == idx)
2579
tmp = av_realloc(program->stream_index, sizeof(unsigned int)*(program->nb_stream_indexes+1));
2582
program->stream_index = tmp;
2583
program->stream_index[program->nb_stream_indexes++] = idx;
2553
2588
/* "user interface" functions */
2589
static void dump_stream_format(AVFormatContext *ic, int i, int index, int is_output)
2592
int flags = (is_output ? ic->oformat->flags : ic->iformat->flags);
2593
AVStream *st = ic->streams[i];
2594
int g = ff_gcd(st->time_base.num, st->time_base.den);
2595
avcodec_string(buf, sizeof(buf), st->codec, is_output);
2596
av_log(NULL, AV_LOG_INFO, " Stream #%d.%d", index, i);
2597
/* the pid is an important information, so we display it */
2598
/* XXX: add a generic system */
2599
if (flags & AVFMT_SHOW_IDS)
2600
av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
2601
if (strlen(st->language) > 0)
2602
av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
2603
av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
2604
av_log(NULL, AV_LOG_INFO, ": %s", buf);
2605
if(st->codec->codec_type == CODEC_TYPE_VIDEO){
2606
if(st->r_frame_rate.den && st->r_frame_rate.num)
2607
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(r)", av_q2d(st->r_frame_rate));
2608
/* else if(st->time_base.den && st->time_base.num)
2609
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(m)", 1/av_q2d(st->time_base));*/
2611
av_log(NULL, AV_LOG_INFO, ", %5.2f tb(c)", 1/av_q2d(st->codec->time_base));
2613
av_log(NULL, AV_LOG_INFO, "\n");
2555
2616
void dump_format(AVFormatContext *ic,
2557
2618
const char *url,
2563
2623
av_log(NULL, AV_LOG_INFO, "%s #%d, %s, %s '%s':\n",
2564
2624
is_output ? "Output" : "Input",
2597
2657
av_log(NULL, AV_LOG_INFO, "\n");
2599
for(i=0;i<ic->nb_streams;i++) {
2600
AVStream *st = ic->streams[i];
2601
int g= ff_gcd(st->time_base.num, st->time_base.den);
2602
avcodec_string(buf, sizeof(buf), st->codec, is_output);
2603
av_log(NULL, AV_LOG_INFO, " Stream #%d.%d", index, i);
2604
/* the pid is an important information, so we display it */
2605
/* XXX: add a generic system */
2607
flags = ic->oformat->flags;
2609
flags = ic->iformat->flags;
2610
if (flags & AVFMT_SHOW_IDS) {
2611
av_log(NULL, AV_LOG_INFO, "[0x%x]", st->id);
2613
if (strlen(st->language) > 0) {
2614
av_log(NULL, AV_LOG_INFO, "(%s)", st->language);
2616
av_log(NULL, AV_LOG_DEBUG, ", %d/%d", st->time_base.num/g, st->time_base.den/g);
2617
av_log(NULL, AV_LOG_INFO, ": %s", buf);
2618
if(st->codec->codec_type == CODEC_TYPE_VIDEO){
2619
if(st->r_frame_rate.den && st->r_frame_rate.num)
2620
av_log(NULL, AV_LOG_INFO, ", %5.2f fps(r)", av_q2d(st->r_frame_rate));
2621
/* else if(st->time_base.den && st->time_base.num)
2622
av_log(NULL, AV_LOG_INFO, ", %5.2f fps(m)", 1/av_q2d(st->time_base));*/
2624
av_log(NULL, AV_LOG_INFO, ", %5.2f fps(c)", 1/av_q2d(st->codec->time_base));
2626
av_log(NULL, AV_LOG_INFO, "\n");
2659
if(ic->nb_programs) {
2661
for(j=0; j<ic->nb_programs; j++) {
2662
av_log(NULL, AV_LOG_INFO, " Program %d %s\n", ic->programs[j]->id,
2663
ic->programs[j]->name ? ic->programs[j]->name : "");
2664
for(k=0; k<ic->programs[j]->nb_stream_indexes; k++)
2665
dump_stream_format(ic, ic->programs[j]->stream_index[k], index, is_output);
2668
for(i=0;i<ic->nb_streams;i++)
2669
dump_stream_format(ic, i, index, is_output);
2633
int frame_rate, frame_rate_base;
2636
static AbvEntry frame_abvs[] = {
2637
{ "ntsc", 720, 480, 30000, 1001 },
2638
{ "pal", 720, 576, 25, 1 },
2639
{ "qntsc", 352, 240, 30000, 1001 }, /* VCD compliant ntsc */
2640
{ "qpal", 352, 288, 25, 1 }, /* VCD compliant pal */
2641
{ "sntsc", 640, 480, 30000, 1001 }, /* square pixel ntsc */
2642
{ "spal", 768, 576, 25, 1 }, /* square pixel pal */
2643
{ "film", 352, 240, 24, 1 },
2644
{ "ntsc-film", 352, 240, 24000, 1001 },
2645
{ "sqcif", 128, 96, 0, 0 },
2646
{ "qcif", 176, 144, 0, 0 },
2647
{ "cif", 352, 288, 0, 0 },
2648
{ "4cif", 704, 576, 0, 0 },
2652
* parses width and height out of string str.
2654
2672
int parse_image_size(int *width_ptr, int *height_ptr, const char *str)
2657
int n = sizeof(frame_abvs) / sizeof(AbvEntry);
2659
int frame_width = 0, frame_height = 0;
2662
if (!strcmp(frame_abvs[i].abv, str)) {
2663
frame_width = frame_abvs[i].width;
2664
frame_height = frame_abvs[i].height;
2670
frame_width = strtol(p, (char **)&p, 10);
2673
frame_height = strtol(p, (char **)&p, 10);
2675
if (frame_width <= 0 || frame_height <= 0)
2677
*width_ptr = frame_width;
2678
*height_ptr = frame_height;
2683
* Converts frame rate from string to a fraction.
2685
* First we try to get an exact integer or fractional frame rate.
2686
* If this fails we convert the frame rate to a double and return
2687
* an approximate fraction using the DEFAULT_FRAME_RATE_BASE.
2689
int parse_frame_rate(int *frame_rate, int *frame_rate_base, const char *arg)
2694
/* First, we check our abbreviation table */
2695
for (i = 0; i < sizeof(frame_abvs)/sizeof(*frame_abvs); ++i)
2696
if (!strcmp(frame_abvs[i].abv, arg)) {
2697
*frame_rate = frame_abvs[i].frame_rate;
2698
*frame_rate_base = frame_abvs[i].frame_rate_base;
2702
/* Then, we try to parse it as fraction */
2703
cp = strchr(arg, '/');
2705
cp = strchr(arg, ':');
2708
*frame_rate = strtol(arg, &cpp, 10);
2709
if (cpp != arg || cpp == cp)
2710
*frame_rate_base = strtol(cp+1, &cpp, 10);
2715
/* Finally we give up and parse it as double */
2716
AVRational time_base = av_d2q(strtod(arg, 0), DEFAULT_FRAME_RATE_BASE);
2717
*frame_rate_base = time_base.den;
2718
*frame_rate = time_base.num;
2720
if (!*frame_rate || !*frame_rate_base)
2727
* Converts date string to number of seconds since Jan 1st, 1970.
2731
* - If not a duration:
2732
* [{YYYY-MM-DD|YYYYMMDD}]{T| }{HH[:MM[:SS[.m...]]][Z]|HH[MM[SS[.m...]]][Z]}
2733
* Time is localtime unless Z is suffixed to the end. In this case GMT
2734
* Return the date in micro seconds since 1970
2737
* HH[:MM[:SS[.m...]]]
2741
#ifndef CONFIG_WINCE
2674
return av_parse_video_frame_size(width_ptr, height_ptr, str);
2677
int parse_frame_rate(int *frame_rate_num, int *frame_rate_den, const char *arg)
2679
AVRational frame_rate;
2680
int ret = av_parse_video_frame_rate(&frame_rate, arg);
2681
*frame_rate_num= frame_rate.num;
2682
*frame_rate_den= frame_rate.den;
2687
* Gets the current time in microseconds.
2689
int64_t av_gettime(void)
2692
gettimeofday(&tv,NULL);
2693
return (int64_t)tv.tv_sec * 1000000 + tv.tv_usec;
2742
2696
int64_t parse_date(const char *datestr, int duration)
2964
* Print nice hexa dump of a buffer
2965
* @param f stream for output
2967
* @param size buffer size
2969
void av_hex_dump(FILE *f, uint8_t *buf, int size)
2906
static void hex_dump_internal(void *avcl, FILE *f, int level, uint8_t *buf, int size)
2971
2908
int len, i, j, c;
2909
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
2973
2911
for(i=0;i<size;i+=16) {
2974
2912
len = size - i;
2977
fprintf(f, "%08x ", i);
2978
2916
for(j=0;j<16;j++) {
2980
fprintf(f, " %02x", buf[i+j]);
2918
PRINT(" %02x", buf[i+j]);
2985
2923
for(j=0;j<len;j++) {
2987
2925
if (c < ' ' || c > '~')
2989
fprintf(f, "%c", c);
2996
* Print on 'f' a nice dump of a packet
2997
* @param f stream for output
2998
* @param pkt packet to dump
2999
* @param dump_payload true if the payload must be displayed too
2934
void av_hex_dump(FILE *f, uint8_t *buf, int size)
2936
hex_dump_internal(NULL, f, 0, buf, size);
2939
void av_hex_dump_log(void *avcl, int level, uint8_t *buf, int size)
2941
hex_dump_internal(avcl, NULL, level, buf, size);
3001
2944
//FIXME needs to know the time_base
3002
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
2945
static void pkt_dump_internal(void *avcl, FILE *f, int level, AVPacket *pkt, int dump_payload)
3004
fprintf(f, "stream #%d:\n", pkt->stream_index);
3005
fprintf(f, " keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
3006
fprintf(f, " duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
2947
#define PRINT(...) do { if (!f) av_log(avcl, level, __VA_ARGS__); else fprintf(f, __VA_ARGS__); } while(0)
2948
PRINT("stream #%d:\n", pkt->stream_index);
2949
PRINT(" keyframe=%d\n", ((pkt->flags & PKT_FLAG_KEY) != 0));
2950
PRINT(" duration=%0.3f\n", (double)pkt->duration / AV_TIME_BASE);
3007
2951
/* DTS is _always_ valid after av_read_frame() */
3008
fprintf(f, " dts=");
3009
2953
if (pkt->dts == AV_NOPTS_VALUE)
3012
fprintf(f, "%0.3f", (double)pkt->dts / AV_TIME_BASE);
3013
/* PTS may be not known if B frames are present */
3014
fprintf(f, " pts=");
2956
PRINT("%0.3f", (double)pkt->dts / AV_TIME_BASE);
2957
/* PTS may not be known if B-frames are present. */
3015
2959
if (pkt->pts == AV_NOPTS_VALUE)
3018
fprintf(f, "%0.3f", (double)pkt->pts / AV_TIME_BASE);
3020
fprintf(f, " size=%d\n", pkt->size);
2962
PRINT("%0.3f", (double)pkt->pts / AV_TIME_BASE);
2964
PRINT(" size=%d\n", pkt->size);
3021
2966
if (dump_payload)
3022
2967
av_hex_dump(f, pkt->data, pkt->size);
2970
void av_pkt_dump(FILE *f, AVPacket *pkt, int dump_payload)
2972
pkt_dump_internal(NULL, f, 0, pkt, dump_payload);
2975
void av_pkt_dump_log(void *avcl, int level, AVPacket *pkt, int dump_payload)
2977
pkt_dump_internal(avcl, NULL, level, pkt, dump_payload);
3025
2980
void url_split(char *proto, int proto_size,
3026
2981
char *authorization, int authorization_size,
3027
2982
char *hostname, int hostname_size,
3029
2984
char *path, int path_size,
3030
2985
const char *url)
3040
while (*p != ':' && *p != '\0') {
3041
if ((q - proto) < proto_size - 1)
3047
if (authorization_size > 0)
3048
authorization[0] = '\0';
3052
if (hostname_size > 0)
2987
const char *p, *ls, *at, *col, *brk;
2989
if (port_ptr) *port_ptr = -1;
2990
if (proto_size > 0) proto[0] = 0;
2991
if (authorization_size > 0) authorization[0] = 0;
2992
if (hostname_size > 0) hostname[0] = 0;
2993
if (path_size > 0) path[0] = 0;
2995
/* parse protocol */
2996
if ((p = strchr(url, ':'))) {
2997
av_strlcpy(proto, url, FFMIN(proto_size, p + 1 - url));
3056
char *at,*slash; // PETR: position of '@' character and '/' character
3063
at = strchr(p,'@'); // PETR: get the position of '@'
3064
slash = strchr(p,'/'); // PETR: get position of '/' - end of hostname
3065
if (at && slash && at > slash) at = NULL; // PETR: not interested in '@' behind '/'
3067
q = at ? authorization : hostname; // PETR: if '@' exists starting with auth.
3069
while ((at || *p != ':') && *p != '/' && *p != '?' && *p != '\0') { // PETR:
3070
if (*p == '@') { // PETR: passed '@'
3071
if (authorization_size > 0)
3075
} else if (!at) { // PETR: hostname
3076
if ((q - hostname) < hostname_size - 1)
3079
if ((q - authorization) < authorization_size - 1)
3084
if (hostname_size > 0)
3088
port = strtoul(p, (char **)&p, 10);
3093
pstrcpy(path, path_size, p);
3002
/* no protocol means plain filename */
3003
av_strlcpy(path, url, path_size);
3007
/* separate path from hostname */
3008
ls = strchr(p, '/');
3010
ls = strchr(p, '?');
3012
av_strlcpy(path, ls, path_size);
3014
ls = &p[strlen(p)]; // XXX
3016
/* the rest is hostname, use that to parse auth/port */
3018
/* authorization (user[:pass]@hostname) */
3019
if ((at = strchr(p, '@')) && at < ls) {
3020
av_strlcpy(authorization, p,
3021
FFMIN(authorization_size, at + 1 - p));
3022
p = at + 1; /* skip '@' */
3025
if (*p == '[' && (brk = strchr(p, ']')) && brk < ls) {
3027
av_strlcpy(hostname, p + 1,
3028
FFMIN(hostname_size, brk - p));
3029
if (brk[1] == ':' && port_ptr)
3030
*port_ptr = atoi(brk + 2);
3031
} else if ((col = strchr(p, ':')) && col < ls) {
3032
av_strlcpy(hostname, p,
3033
FFMIN(col + 1 - p, hostname_size));
3034
if (port_ptr) *port_ptr = atoi(col + 1);
3036
av_strlcpy(hostname, p,
3037
FFMIN(ls + 1 - p, hostname_size));
3097
* Set the pts for a given stream.
3100
* @param pts_wrap_bits number of bits effectively used by the pts
3101
* (used for wrap control, 33 is the value for MPEG)
3102
* @param pts_num numerator to convert to seconds (MPEG: 1)
3103
* @param pts_den denominator to convert to seconds (MPEG: 90000)
3105
3041
void av_set_pts_info(AVStream *s, int pts_wrap_bits,
3106
3042
int pts_num, int pts_den)