Changeset 42162 for titan/libeplayer3/container/container_ffmpeg.c
- Timestamp:
- 04/12/18 15:06:43 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
titan/libeplayer3/container/container_ffmpeg.c
r41899 r42162 146 146 static int32_t seek_target_flag = 0; 147 147 148 static int32_t mutexInitialized = 0; 149 148 150 /* ***************************** */ 149 151 /* Prototypes */ … … 164 166 progressive_playback = val; 165 167 } 168 169 static void initMutex(void) 170 { 171 pthread_mutex_init(&mutex, NULL); 172 mutexInitialized = 1; 173 } 174 175 static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line) 176 { 177 ffmpeg_printf(100, "::%d requesting mutex\n", line); 178 179 if (!mutexInitialized) 180 { 181 initMutex(); 182 } 183 184 pthread_mutex_lock(&mutex); 185 186 ffmpeg_printf(100, "::%d received mutex\n", line); 187 } 188 189 static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line) 190 { 191 pthread_mutex_unlock(&mutex); 192 193 ffmpeg_printf(100, "::%d released mutex\n", line); 194 } 195 196 typedef int32_t (* Write_FN) (void *, void *); 197 198 static int32_t Write(Write_FN WriteFun, void *context, void *privateData, int64_t pts) 199 { 200 /* Because Write is blocking we will release mutex which protect 201 * avformat structures, during write time 202 */ 203 int32_t ret = 0; 204 releaseMutex(__FILE__, __FUNCTION__,__LINE__); 205 ret = WriteFun(context, privateData); 206 getMutex(__FILE__, __FUNCTION__,__LINE__); 207 return ret; 208 } 209 166 210 167 211 #include "buff_ffmpeg.c" … … 426 470 } 427 471 428 static int32_t mutexInitialized = 0;472 //static int32_t mutexInitialized = 0; 429 473 430 474 void sel_program_id_set(const int32_t val) … … 496 540 { 497 541 return av_dict_set(&avio_opts, key, value, flags); 498 }499 500 static void initMutex(void)501 {502 pthread_mutex_init(&mutex, NULL);503 mutexInitialized = 1;504 }505 506 static void getMutex(const char *filename __attribute__((unused)), const char *function __attribute__((unused)), int32_t line)507 {508 ffmpeg_printf(100, "::%d requesting mutex\n", line);509 510 if (!mutexInitialized)511 {512 initMutex();513 }514 515 pthread_mutex_lock(&mutex);516 517 ffmpeg_printf(100, "::%d received mutex\n", line);518 }519 520 static void releaseMutex(const char *filename __attribute__((unused)), const const char *function __attribute__((unused)), int32_t line)521 {522 pthread_mutex_unlock(&mutex);523 524 ffmpeg_printf(100, "::%d released mutex\n", line);525 542 } 526 543 … … 703 720 pts = INVALID_PTS_VALUE; 704 721 } 722 else 723 { 724 pts &= 0x01FFFFFFFF; // PES header can handle only 33 bit PTS 725 } 705 726 706 727 return pts; … … 798 819 while ( context && context->playback && context->playback->isPlaying ) 799 820 { 821 /* When user press PAUSE we call pause on AUDIO and VIDEO decoders, 822 * we will not wait here because we can still fill 823 * DVB drivers buffers at PAUSE time 824 * 825 * In the future we can add buffering queue before injection in to 826 * AUDIO, VIDEO decoders, so we can not wait here 827 */ 828 #ifdef __sh__ 800 829 //IF MOVIE IS PAUSED, WAIT 801 830 if (context->playback->isPaused) … … 806 835 continue; 807 836 } 837 #endif 808 838 809 839 if (context->playback->isSeeking) … … 929 959 930 960 reset_finish_timeout(); 931 932 if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) 933 { 934 ffmpeg_err("error getting video track\n"); 961 if(avContextTab[cAVIdx]->streams[packet.stream_index]->discard != AVDISCARD_ALL) 962 { 963 if (context->manager->video->Command(context, MANAGER_GET_TRACK, &videoTrack) < 0) 964 { 965 ffmpeg_err("error getting video track\n"); 966 } 967 968 if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0) 969 { 970 ffmpeg_err("error getting audio track\n"); 971 } 972 973 if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0) 974 { 975 ffmpeg_err("error getting subtitle track\n"); 976 } 977 } 978 else 979 { 980 ffmpeg_printf(1, "SKIP DISCARDED PACKET stream_index[%d] pid[%d]\n", packet.size, (int)packet.stream_index, pid); 935 981 } 936 982 937 if (context->manager->audio->Command(context, MANAGER_GET_TRACK, &audioTrack) < 0)938 {939 ffmpeg_err("error getting audio track\n");940 }941 942 if (context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &subtitleTrack) < 0)943 {944 ffmpeg_err("error getting subtitle track\n");945 }946 947 983 ffmpeg_printf(200, "packet.size %d - index %d\n", packet.size, pid); 948 984 … … 1037 1073 } 1038 1074 1039 if ( context->output->video->Write(context, &avOut) < 0)1075 if (Write(context->output->video->Write, context, &avOut, pts) < 0) 1040 1076 { 1041 1077 ffmpeg_err("writing data to video device failed\n"); … … 1113 1149 avOut.type = "audio"; 1114 1150 1115 if ( context->output->audio->Write(context, &avOut) < 0)1151 if (Write(context->output->audio->Write, context, &avOut, pts) < 0) 1116 1152 { 1117 1153 ffmpeg_err("(raw pcm) writing data to audio device failed\n"); … … 1308 1344 avOut.type = "audio"; 1309 1345 1310 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)1346 if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) 1311 1347 { 1312 1348 ffmpeg_err("writing data to audio device failed\n"); … … 1331 1367 avOut.type = "audio"; 1332 1368 1333 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)1369 if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) 1334 1370 { 1335 1371 ffmpeg_err("(aac) writing data to audio device failed\n"); … … 1349 1385 avOut.type = "audio"; 1350 1386 1351 if (!context->playback->BackWard && context->output->audio->Write(context, &avOut) < 0)1387 if (!context->playback->BackWard && Write(context->output->audio->Write, context, &avOut, pts) < 0) 1352 1388 { 1353 1389 ffmpeg_err("writing data to audio device failed\n"); … … 1397 1433 //obi (end) 1398 1434 1399 if ( context->output->subtitle->Write(context, &subOut) < 0)1435 if (Write(context->output->subtitle->Write, context, &subOut, pts) < 0) 1400 1436 { 1401 1437 ffmpeg_err("writing data to teletext fifo failed\n"); … … 1545 1581 1546 1582 #ifdef SAM_CUSTOM_IO 1583 typedef struct CustomIOCtx_t 1584 { 1585 FILE *pFile; 1586 FILE *pMoovFile; 1587 int64_t iOffset; 1588 1589 char *szFile; 1590 uint64_t iFileSize; 1591 char *szMoovAtomFile; 1592 uint64_t iMoovAtomOffset; 1593 } CustomIOCtx_t; 1594 1595 CustomIOCtx_t* custom_io_tab[IPTV_AV_CONTEXT_MAX_NUM] = {NULL, NULL}; 1596 1547 1597 int SAM_ReadFunc(void *ptr, uint8_t *buffer, int lSize) 1548 1598 { 1549 size_t ret = fread ( (void *) buffer, (size_t) 1, (size_t) lSize, (FILE *)ptr ); 1550 return (int)ret; 1599 CustomIOCtx_t *io = (CustomIOCtx_t *)ptr; 1600 int ret = 0; 1601 1602 if (!io->pMoovFile) 1603 { 1604 ret = (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pFile ); 1605 } 1606 else 1607 { 1608 if (io->iOffset < io->iMoovAtomOffset) 1609 { 1610 ret = (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pFile ); 1611 buffer += ret; 1612 lSize -= ret; 1613 } 1614 1615 if (io->iOffset + ret >= io->iMoovAtomOffset) 1616 { 1617 if (ret) 1618 { 1619 if (fseeko(io->pMoovFile, io->iOffset + ret - io->iMoovAtomOffset, SEEK_SET)) 1620 { 1621 // something goes wrong 1622 ffmpeg_err("fseeko on moov atom file fail \n"); 1623 lSize = 0; 1624 } 1625 } 1626 1627 ret += (int)fread( (void *) buffer, (size_t) 1, (size_t) lSize, io->pMoovFile ); 1628 } 1629 1630 io->iOffset += ret; 1631 } 1632 return ret; 1551 1633 } 1552 1634 1553 1635 // whence: SEEK_SET, SEEK_CUR, SEEK_END (like fseek) and AVSEEK_SIZE 1554 int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence)1636 int64_t SAM_SeekFunc(void *ptr, int64_t pos, int whence) 1555 1637 { 1556 if( AVSEEK_SIZE == whence ) 1557 { 1558 return -1; 1559 } 1560 int ret = fseeko((FILE *)ptr, (off_t)pos, whence); 1561 if(0 == ret) 1562 { 1563 return (off_t)ftello((FILE *)ptr); 1638 CustomIOCtx_t *io = (CustomIOCtx_t *)ptr; 1639 int64_t ret = -1; 1640 if (!io->pMoovFile) 1641 { 1642 if( AVSEEK_SIZE != whence ) 1643 { 1644 ret = (int64_t)fseeko(io->pFile, (off_t)pos, whence); 1645 if(0 == ret) 1646 { 1647 ret = (int64_t)ftello(io->pFile); 1648 } 1649 } 1650 } 1651 else 1652 { 1653 switch(whence) 1654 { 1655 case SEEK_SET: 1656 ret = pos; 1657 break; 1658 case SEEK_CUR: 1659 ret += pos; 1660 break; 1661 case SEEK_END: 1662 ret = io->iFileSize + pos; 1663 break; 1664 case AVSEEK_SIZE: 1665 return io->iFileSize; 1666 default: 1667 return -1; 1668 } 1669 1670 if (ret >= 0 && ret <= io->iFileSize) 1671 { 1672 if (ret < io->iMoovAtomOffset) 1673 { 1674 if(!fseeko(io->pFile, (off_t)ret, SEEK_SET)) 1675 io->iOffset = ret; 1676 else 1677 ret = -1; 1678 } 1679 else 1680 { 1681 if(!fseeko(io->pMoovFile, (off_t)(ret - io->iMoovAtomOffset), SEEK_SET)) 1682 io->iOffset = ret; 1683 else 1684 ret = -1; 1685 } 1686 } 1687 else 1688 { 1689 ret = -1; 1690 } 1564 1691 } 1565 1692 return ret; 1566 1693 } 1567 1694 1568 AVIOContext* container_ffmpeg_get_avio_context(char *filename, size_t avio_ctx_buffer_size) 1569 { 1570 if(strstr(filename, "file://") == filename) 1571 { 1572 filename += 7; 1573 } 1695 AVIOContext* container_ffmpeg_get_avio_context(CustomIOCtx_t *custom_io, size_t avio_ctx_buffer_size) 1696 { 1697 if(strstr(custom_io->szFile, "file://") == custom_io->szFile) 1698 custom_io->szFile += 7; 1699 1700 custom_io->pFile = fopen(custom_io->szFile, "rb"); 1701 if(NULL == custom_io->pFile) 1702 { 1703 return NULL; 1704 } 1705 1706 if (custom_io->szMoovAtomFile && custom_io->szMoovAtomFile[0] != '\0') 1707 { 1708 if(strstr(custom_io->szMoovAtomFile, "file://") == custom_io->szMoovAtomFile) 1709 custom_io->szMoovAtomFile += 7; 1574 1710 1575 FILE *pFile = fopen(filename, "rb"); 1576 if(NULL == pFile) 1577 { 1711 custom_io->pMoovFile = fopen(custom_io->szMoovAtomFile, "rb"); 1712 if(NULL == custom_io->pMoovFile) 1713 { 1714 fclose(custom_io->pFile); 1578 1715 return NULL; 1579 1716 } 1580 1581 AVIOContext *avio_ctx = NULL; 1582 uint8_t *avio_ctx_buffer = NULL; 1583 1584 avio_ctx_buffer = av_malloc(avio_ctx_buffer_size); 1585 if (!avio_ctx_buffer) 1586 { 1587 return NULL; 1588 } 1589 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, pFile, &SAM_ReadFunc, NULL, &SAM_SeekFunc); 1590 if (!avio_ctx) 1591 { 1592 return NULL; 1593 } 1594 return avio_ctx; 1717 } 1718 1719 AVIOContext *avio_ctx = NULL; 1720 uint8_t *avio_ctx_buffer = NULL; 1721 1722 avio_ctx_buffer = av_malloc(avio_ctx_buffer_size); 1723 if (!avio_ctx_buffer) 1724 { 1725 return NULL; 1726 } 1727 avio_ctx = avio_alloc_context(avio_ctx_buffer, avio_ctx_buffer_size, 0, custom_io, &SAM_ReadFunc, NULL, &SAM_SeekFunc); 1728 if (!avio_ctx) 1729 { 1730 return NULL; 1731 } 1732 return avio_ctx; 1595 1733 } 1596 1734 #endif 1597 1735 1598 int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, int32_t AVIdx)1736 int32_t container_ffmpeg_init_av_context(Context_t *context, char *filename, uint64_t fileSize, char *moovAtomFile, uint64_t moovAtomOffset, int32_t AVIdx) 1599 1737 { 1600 1738 int32_t err = 0; … … 1608 1746 0 == strncmp(filename, "file://", 7)) 1609 1747 { 1610 AVIOContext *avio_ctx = container_ffmpeg_get_avio_context(filename, 4096); 1748 AVIOContext *avio_ctx = NULL; 1749 custom_io_tab[AVIdx] = malloc(sizeof(CustomIOCtx_t)); 1750 sizeof(custom_io_tab[AVIdx], 0x00, sizeof(CustomIOCtx_t)); 1751 1752 custom_io_tab[AVIdx]->szFile = filename; 1753 custom_io_tab[AVIdx]->iFileSize = fileSize; 1754 custom_io_tab[AVIdx]->szMoovAtomFile = moovAtomFile; 1755 custom_io_tab[AVIdx]->iMoovAtomOffset = moovAtomOffset; 1756 1757 avio_ctx = container_ffmpeg_get_avio_context(custom_io_tab[AVIdx], 4096); 1611 1758 if(avio_ctx) 1612 1759 { … … 1616 1763 else 1617 1764 { 1765 free(custom_io_tab[AVIdx]); 1766 custom_io_tab[AVIdx] = NULL; 1618 1767 return cERR_CONTAINER_FFMPEG_OPEN; 1619 1768 } … … 2154 2303 2155 2304 context->playback->abortRequested = 0; 2156 int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, 0); 2305 int32_t res = container_ffmpeg_init_av_context(context, playFilesNames->szFirstFile, playFilesNames->iFirstFileSize, \ 2306 playFilesNames->szFirstMoovAtomFile, playFilesNames->iFirstMoovAtomOffset, 0); 2157 2307 if(0 != res) 2158 2308 { … … 2160 2310 } 2161 2311 2162 if(playFilesNames->szSecondFile) 2163 { 2164 res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, 1); 2312 if(playFilesNames->szSecondFile && playFilesNames->szSecondFile[0] != '\0') 2313 { 2314 res = container_ffmpeg_init_av_context(context, playFilesNames->szSecondFile, playFilesNames->iSecondFileSize, \ 2315 playFilesNames->szSecondMoovAtomFile, playFilesNames->iSecondMoovAtomOffset, 1); 2165 2316 } 2166 2317 … … 2183 2334 int32_t container_ffmpeg_update_tracks(Context_t *context, char *filename, int32_t initial) 2184 2335 { 2185 Track_t *audioTrack = NULL; 2186 Track_t *subtitleTrack = NULL; 2336 Track_t *currAudioTrack = NULL; 2337 Track_t *currSubtitleTrack = NULL; 2338 uint32_t addedVideoTracksCount = 0; 2187 2339 2188 2340 if (terminating) … … 2191 2343 } 2192 2344 2345 getMutex(__FILE__, __FUNCTION__,__LINE__); 2346 2193 2347 if (initial && context->manager->subtitle) 2194 2348 { 2195 context->manager->subtitle->Command(context, MANAGER_GET_TRACK, & subtitleTrack);2349 context->manager->subtitle->Command(context, MANAGER_GET_TRACK, &currSubtitleTrack); 2196 2350 } 2197 2351 2198 2352 if (context->manager->audio) 2199 2353 { 2200 context->manager->audio->Command(context, MANAGER_GET_TRACK, & audioTrack);2354 context->manager->audio->Command(context, MANAGER_GET_TRACK, &currAudioTrack); 2201 2355 } 2202 2356 … … 2217 2371 } 2218 2372 #endif 2219 2220 2373 2221 2374 ffmpeg_printf(20, "dump format\n"); … … 2295 2448 } 2296 2449 2297 if (!isStreamFromSelProg) 2450 if (!isStreamFromSelProg) { 2451 stream->discard = AVDISCARD_ALL; 2452 ffmpeg_printf(1, "cAVIdx[%d]: add DISCARD flag to stream index[%d]\n", cAVIdx, stream->index); 2298 2453 continue; // skip this stream 2454 } 2299 2455 } 2300 2456 … … 2329 2485 case AVMEDIA_TYPE_VIDEO: 2330 2486 ffmpeg_printf(10, "CODEC_TYPE_VIDEO %d\n", get_codecpar(stream)->codec_type); 2331 2487 stream->discard = AVDISCARD_ALL; /* by default we discard all video streams */ 2332 2488 if (encoding != NULL) 2333 2489 { … … 2409 2565 ffmpeg_err("failed to add track %d\n", n); 2410 2566 } 2567 else 2568 { 2569 if (addedVideoTracksCount == 0) /* at now we can handle only first video track */ 2570 { 2571 stream->discard = AVDISCARD_DEFAULT; 2572 } 2573 addedVideoTracksCount += 1; 2574 } 2411 2575 } 2412 2576 } … … 2418 2582 case AVMEDIA_TYPE_AUDIO: 2419 2583 ffmpeg_printf(10, "CODEC_TYPE_AUDIO %d\n",get_codecpar(stream)->codec_type); 2420 2584 stream->discard = AVDISCARD_ALL; 2421 2585 if (encoding != NULL) 2422 2586 { … … 2790 2954 case AVMEDIA_TYPE_NB: 2791 2955 default: 2956 stream->discard = AVDISCARD_ALL; 2792 2957 ffmpeg_err("not handled or unknown codec_type %d\n", get_codecpar(stream)->codec_type); 2793 2958 break; … … 2796 2961 2797 2962 } 2798 2963 2964 if (context->manager->audio) 2965 { 2966 Track_t *Tracks = NULL; 2967 int32_t TrackCount = 0; 2968 int32_t selTrackIdx = -1; 2969 2970 context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); 2971 context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); 2972 if (Tracks && TrackCount) 2973 { 2974 int32_t i; 2975 for (i=0; i < TrackCount; ++i) 2976 { 2977 if (Tracks[i].pending || Tracks[i].Id < 0) 2978 continue; 2979 2980 if (selTrackIdx == -1) 2981 selTrackIdx = i; 2982 2983 if (currAudioTrack && currAudioTrack->Id == Tracks[i].Id) 2984 { 2985 selTrackIdx = i; 2986 break; 2987 } 2988 } 2989 2990 if (selTrackIdx > -1) 2991 { 2992 ((AVStream*)Tracks[selTrackIdx].stream)->discard = AVDISCARD_DEFAULT; 2993 if (!currAudioTrack || currAudioTrack->Id != Tracks[selTrackIdx].Id ) 2994 { 2995 context->manager->audio->Command(context, MANAGER_SET, &Tracks[selTrackIdx].Id); 2996 } 2997 } 2998 } 2999 } 3000 3001 releaseMutex(__FILE__, __FUNCTION__,__LINE__); 2799 3002 return cERR_CONTAINER_FFMPEG_NO_ERROR; 2800 3003 } … … 3119 3322 } 3120 3323 3121 getMutex(__FILE__, __FUNCTION__,__LINE__);3324 // getMutex(__FILE__, __FUNCTION__,__LINE__); 3122 3325 3123 3326 if (!context->playback || !context->playback->isPlaying) … … 3138 3341 */ 3139 3342 3343 getMutex(__FILE__, __FUNCTION__,__LINE__); 3140 3344 off_t pos = avio_tell(avContextTab[0]->pb); 3345 releaseMutex(__FILE__, __FUNCTION__,__LINE__); 3141 3346 3142 3347 ffmpeg_printf(10, "pos %lld %d\n", pos, avContextTab[0]->bit_rate); … … 3172 3377 } 3173 3378 3174 releaseMutex(__FILE__, __FUNCTION__,__LINE__);3379 // releaseMutex(__FILE__, __FUNCTION__,__LINE__); 3175 3380 return cERR_CONTAINER_FFMPEG_NO_ERROR; 3176 3381 } … … 3233 3438 { 3234 3439 ffmpeg_printf(10, "track %d\n", *arg); 3440 getMutex(__FILE__, __FUNCTION__,__LINE__); 3441 if (context->manager->audio) 3442 { 3443 Track_t *Tracks = NULL; 3444 int32_t TrackCount = 0; 3445 3446 context->manager->audio->Command(context, MANAGER_REF_LIST, &Tracks); 3447 context->manager->audio->Command(context, MANAGER_REF_LIST_SIZE, &TrackCount); 3448 if (Tracks && TrackCount) 3449 { 3450 int32_t i; 3451 for (i=0; i < TrackCount; ++i) 3452 { 3453 ((AVStream*)Tracks[i].stream)->discard = Tracks[i].Id == *arg ? AVDISCARD_DEFAULT : AVDISCARD_ALL; 3454 } 3455 } 3456 } 3457 releaseMutex(__FILE__, __FUNCTION__,__LINE__); 3235 3458 3236 3459 /* Hellmaster1024: nothing to do here!*/ 3237 int64_t sec = - 5;3460 int64_t sec = -1; 3238 3461 context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec); 3239 3462 return cERR_CONTAINER_FFMPEG_NO_ERROR; … … 3249 3472 * but now we will not ignore subtitle frame 3250 3473 */ 3251 int64_t sec = - 5;3474 int64_t sec = -1; 3252 3475 context->playback->Command(context, PLAYBACK_SEEK, (void*)&sec); 3253 3476 //obi
Note: See TracChangeset
for help on using the changeset viewer.